summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/BrainF/BrainF.cpp20
-rw-r--r--examples/BrainF/BrainF.h9
-rw-r--r--examples/BrainF/BrainFDriver.cpp25
-rw-r--r--examples/BrainF/Makefile15
-rw-r--r--examples/ExceptionDemo/ExceptionDemo.cpp6
-rw-r--r--examples/ExceptionDemo/Makefile16
-rw-r--r--examples/Fibonacci/CMakeLists.txt1
-rw-r--r--examples/Fibonacci/Makefile17
-rw-r--r--examples/Fibonacci/fibonacci.cpp17
-rw-r--r--examples/HowToUseJIT/HowToUseJIT.cpp12
-rw-r--r--examples/HowToUseJIT/Makefile15
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/CMakeLists.txt8
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt17
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h102
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter1/toy.cpp1219
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt17
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h133
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter2/toy.cpp1219
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter3/CMakeLists.txt19
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h144
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter3/toy.cpp1219
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter4/CMakeLists.txt19
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h232
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter4/toy.cpp1228
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/CMakeLists.txt21
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h264
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/RemoteJITUtils.h74
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/CMakeLists.txt17
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/server.cpp119
-rw-r--r--examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp1294
-rw-r--r--examples/Kaleidoscope/CMakeLists.txt2
-rw-r--r--examples/Kaleidoscope/Chapter2/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter2/toy.cpp29
-rw-r--r--examples/Kaleidoscope/Chapter3/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter3/toy.cpp63
-rw-r--r--examples/Kaleidoscope/Chapter4/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter4/toy.cpp71
-rw-r--r--examples/Kaleidoscope/Chapter5/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter5/toy.cpp111
-rw-r--r--examples/Kaleidoscope/Chapter6/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp117
-rw-r--r--examples/Kaleidoscope/Chapter7/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter7/toy.cpp133
-rw-r--r--examples/Kaleidoscope/Chapter8/CMakeLists.txt6
-rw-r--r--examples/Kaleidoscope/Chapter8/Makefile15
-rw-r--r--examples/Kaleidoscope/Chapter8/toy.cpp509
-rw-r--r--examples/Kaleidoscope/Chapter9/CMakeLists.txt (renamed from examples/Kaleidoscope/Orc/initial/CMakeLists.txt)5
-rw-r--r--examples/Kaleidoscope/Chapter9/toy.cpp1445
-rw-r--r--examples/Kaleidoscope/MCJIT/cached/Makefile11
-rw-r--r--examples/Kaleidoscope/MCJIT/cached/toy-jit.cpp66
-rw-r--r--examples/Kaleidoscope/MCJIT/cached/toy.cpp54
-rw-r--r--examples/Kaleidoscope/MCJIT/complete/Makefile4
-rw-r--r--examples/Kaleidoscope/MCJIT/complete/toy.cpp52
-rw-r--r--examples/Kaleidoscope/MCJIT/initial/Makefile4
-rw-r--r--examples/Kaleidoscope/MCJIT/initial/toy.cpp52
-rw-r--r--examples/Kaleidoscope/MCJIT/lazy/Makefile7
-rw-r--r--examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp64
-rw-r--r--examples/Kaleidoscope/MCJIT/lazy/toy.cpp52
-rw-r--r--examples/Kaleidoscope/Makefile15
-rw-r--r--examples/Kaleidoscope/Orc/CMakeLists.txt4
-rw-r--r--examples/Kaleidoscope/Orc/fully_lazy/CMakeLists.txt13
-rw-r--r--examples/Kaleidoscope/Orc/fully_lazy/Makefile17
-rw-r--r--examples/Kaleidoscope/Orc/fully_lazy/README.txt21
-rw-r--r--examples/Kaleidoscope/Orc/fully_lazy/toy.cpp1440
-rw-r--r--examples/Kaleidoscope/Orc/initial/Makefile17
-rw-r--r--examples/Kaleidoscope/Orc/initial/README.txt13
-rw-r--r--examples/Kaleidoscope/Orc/initial/toy.cpp1335
-rw-r--r--examples/Kaleidoscope/Orc/lazy_codegen/CMakeLists.txt12
-rw-r--r--examples/Kaleidoscope/Orc/lazy_codegen/Makefile17
-rw-r--r--examples/Kaleidoscope/Orc/lazy_codegen/README.txt13
-rw-r--r--examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp1339
-rw-r--r--examples/Kaleidoscope/Orc/lazy_irgen/CMakeLists.txt12
-rw-r--r--examples/Kaleidoscope/Orc/lazy_irgen/Makefile17
-rw-r--r--examples/Kaleidoscope/Orc/lazy_irgen/README.txt16
-rw-r--r--examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp1370
-rw-r--r--examples/Kaleidoscope/include/KaleidoscopeJIT.h20
-rw-r--r--examples/Makefile32
-rw-r--r--examples/ModuleMaker/Makefile14
-rw-r--r--examples/ModuleMaker/ModuleMaker.cpp6
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter2/Makefile22
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter3/Makefile24
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter4/Makefile25
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter5/Makefile25
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter6/Makefile34
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter7/Makefile34
-rw-r--r--examples/OCaml-Kaleidoscope/Makefile15
-rw-r--r--examples/ParallelJIT/CMakeLists.txt4
-rw-r--r--examples/ParallelJIT/Makefile17
-rw-r--r--examples/ParallelJIT/ParallelJIT.cpp18
89 files changed, 9514 insertions, 6927 deletions
diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp
index d8c54b50b8549..97ecdab0fe950 100644
--- a/examples/BrainF/BrainF.cpp
+++ b/examples/BrainF/BrainF.cpp
@@ -1,11 +1,11 @@
-//===-- BrainF.cpp - BrainF compiler example ----------------------------===//
+//===-- BrainF.cpp - BrainF compiler example ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// This class compiles the BrainF language into LLVM assembly.
//
@@ -21,13 +21,25 @@
// [ while(*h) { Start loop
// ] } End loop
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "BrainF.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include <cstdlib>
#include <iostream>
using namespace llvm;
diff --git a/examples/BrainF/BrainF.h b/examples/BrainF/BrainF.h
index 15e9e0847141f..587be141b98f0 100644
--- a/examples/BrainF/BrainF.h
+++ b/examples/BrainF/BrainF.h
@@ -1,16 +1,16 @@
-//===-- BrainF.h - BrainF compiler class ----------------------*- C++ -*-===//
+//===-- BrainF.h - BrainF compiler class ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// This class stores the data for the BrainF compiler so it doesn't have
// to pass all of it around. The main method is parse.
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#ifndef BRAINF_H
#define BRAINF_H
@@ -18,6 +18,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include <istream>
using namespace llvm;
@@ -91,4 +92,4 @@ class BrainF {
Value *curhead;
};
-#endif
+#endif // BRAINF_H
diff --git a/examples/BrainF/BrainFDriver.cpp b/examples/BrainF/BrainFDriver.cpp
index 1a38c67b0d4a0..d19427add876a 100644
--- a/examples/BrainF/BrainFDriver.cpp
+++ b/examples/BrainF/BrainFDriver.cpp
@@ -1,11 +1,11 @@
-//===-- BrainFDriver.cpp - BrainF compiler driver -----------------------===//
+//===-- BrainFDriver.cpp - BrainF compiler driver -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// This program converts the BrainF language into LLVM assembly,
// which it can then run using the JIT or output as BitCode.
@@ -22,21 +22,37 @@
//
// lli prog.bf.bc #Run generated BitCode
//
-//===--------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
#include "BrainF.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdlib>
#include <fstream>
#include <iostream>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
+
using namespace llvm;
//Command line options
@@ -53,7 +69,6 @@ ArrayBoundsChecking("abc", cl::desc("Enable array bounds checking"));
static cl::opt<bool>
JIT("jit", cl::desc("Run program Just-In-Time"));
-
//Add main function so can be fully compiled
void addMainFunction(Module *mod) {
//define i32 @main(i32 %argc, i8 **%argv)
@@ -88,7 +103,7 @@ void addMainFunction(Module *mod) {
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " BrainF compiler\n");
- LLVMContext &Context = getGlobalContext();
+ LLVMContext Context;
if (InputFilename == "") {
errs() << "Error: You must specify the filename of the program to "
diff --git a/examples/BrainF/Makefile b/examples/BrainF/Makefile
deleted file mode 100644
index 3e36e0761758d..0000000000000
--- a/examples/BrainF/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/BrainF/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = BrainF
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := mcjit bitwriter nativecodegen interpreter
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp
index 444ee2649fa73..0afc3fdf59aa4 100644
--- a/examples/ExceptionDemo/ExceptionDemo.cpp
+++ b/examples/ExceptionDemo/ExceptionDemo.cpp
@@ -1951,12 +1951,12 @@ int main(int argc, char *argv[]) {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
- llvm::LLVMContext &context = llvm::getGlobalContext();
- llvm::IRBuilder<> theBuilder(context);
+ llvm::LLVMContext Context;
+ llvm::IRBuilder<> theBuilder(Context);
// Make the module, which holds all the code.
std::unique_ptr<llvm::Module> Owner =
- llvm::make_unique<llvm::Module>("my cool jit", context);
+ llvm::make_unique<llvm::Module>("my cool jit", Context);
llvm::Module *module = Owner.get();
std::unique_ptr<llvm::RTDyldMemoryManager> MemMgr(new llvm::SectionMemoryManager());
diff --git a/examples/ExceptionDemo/Makefile b/examples/ExceptionDemo/Makefile
deleted file mode 100644
index 895b61dafcd3c..0000000000000
--- a/examples/ExceptionDemo/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- examples/ExceptionDemo/Makefile --------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===---------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = ExceptionDemo
-EXAMPLE_TOOL = 1
-REQUIRES_EH = 1
-
-LINK_COMPONENTS := mcjit nativecodegen
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Fibonacci/CMakeLists.txt b/examples/Fibonacci/CMakeLists.txt
index 087ccdd7d841d..e294a2523759a 100644
--- a/examples/Fibonacci/CMakeLists.txt
+++ b/examples/Fibonacci/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
Interpreter
MC
+ MCJIT
Support
nativecodegen
)
diff --git a/examples/Fibonacci/Makefile b/examples/Fibonacci/Makefile
deleted file mode 100644
index c99110a221199..0000000000000
--- a/examples/Fibonacci/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- examples/Fibonacci/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-TOOLNAME = Fibonacci
-EXAMPLE_TOOL = 1
-
-# Link in JIT support
-LINK_COMPONENTS := interpreter mcjit nativecodegen
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp
index ecb49eb92e1ac..16e52bf040990 100644
--- a/examples/Fibonacci/fibonacci.cpp
+++ b/examples/Fibonacci/fibonacci.cpp
@@ -23,16 +23,29 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/APInt.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <vector>
using namespace llvm;
@@ -77,7 +90,6 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) {
CallInst *CallFibX2 = CallInst::Create(FibF, Sub, "fibx2", RecurseBB);
CallFibX2->setTailCall();
-
// fib(x-1)+fib(x-2)
Value *Sum = BinaryOperator::CreateAdd(CallFibX1, CallFibX2,
"addresult", RecurseBB);
@@ -92,6 +104,7 @@ int main(int argc, char **argv) {
int n = argc > 1 ? atol(argv[1]) : 24;
InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
LLVMContext Context;
// Create some module to put our function into it.
diff --git a/examples/HowToUseJIT/HowToUseJIT.cpp b/examples/HowToUseJIT/HowToUseJIT.cpp
index e0bf6a00bf017..0050d27b45d7f 100644
--- a/examples/HowToUseJIT/HowToUseJIT.cpp
+++ b/examples/HowToUseJIT/HowToUseJIT.cpp
@@ -35,22 +35,30 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <memory>
+#include <vector>
using namespace llvm;
int main() {
-
InitializeNativeTarget();
LLVMContext Context;
diff --git a/examples/HowToUseJIT/Makefile b/examples/HowToUseJIT/Makefile
deleted file mode 100644
index 26a25a12bf23a..0000000000000
--- a/examples/HowToUseJIT/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/HowToUseJIT/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = HowToUseJIT
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := mcjit interpreter nativecodegen
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/BuildingAJIT/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/CMakeLists.txt
new file mode 100644
index 0000000000000..947b5a3a3271e
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_subdirectory(Chapter1)
+add_subdirectory(Chapter2)
+add_subdirectory(Chapter3)
+add_subdirectory(Chapter4)
+
+if (NOT WIN32)
+ add_subdirectory(Chapter5)
+endif()
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt
new file mode 100644
index 0000000000000..657a14be87d0f
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter1/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ RuntimeDyld
+ ScalarOpts
+ Support
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch1
+ toy.cpp
+ )
+
+export_executable_symbols(BuildingAJIT-Ch1)
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h
new file mode 100644
index 0000000000000..35c871affec8b
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h
@@ -0,0 +1,102 @@
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+class KaleidoscopeJIT {
+private:
+ std::unique_ptr<TargetMachine> TM;
+ const DataLayout DL;
+ ObjectLinkingLayer<> ObjectLayer;
+ IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
+
+public:
+ typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;
+
+ KaleidoscopeJIT()
+ : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
+ }
+
+ TargetMachine &getTargetMachine() { return *TM; }
+
+ ModuleHandle addModule(std::unique_ptr<Module> M) {
+ // Build our symbol resolver:
+ // Lambda 1: Look back into the JIT itself to find symbols that are part of
+ // the same "logical dylib".
+ // Lambda 2: Search for external symbols in the host process.
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = CompileLayer.findSymbol(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ if (auto SymAddr =
+ RTDyldMemoryManager::getSymbolAddressInProcess(Name))
+ return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported);
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ // Build a singlton module set to hold our module.
+ std::vector<std::unique_ptr<Module>> Ms;
+ Ms.push_back(std::move(M));
+
+ // Add the set to the JIT with the resolver we created above and a newly
+ // created SectionMemoryManager.
+ return CompileLayer.addModuleSet(std::move(Ms),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
+ }
+
+ JITSymbol findSymbol(const std::string Name) {
+ std::string MangledName;
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ return CompileLayer.findSymbol(MangledNameStream.str(), true);
+ }
+
+ void removeModule(ModuleHandle H) {
+ CompileLayer.removeModuleSet(H);
+ }
+
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter1/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter1/toy.cpp
new file mode 100644
index 0000000000000..22b0819cd71a9
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter1/toy.cpp
@@ -0,0 +1,1219 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "KaleidoscopeJIT.h"
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = getchar();
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = getchar())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = getchar();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = getchar();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = getchar();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+namespace {
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(const std::string &Name) : Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
+ Value *codegen() override;
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+
+public:
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ Function *codegen();
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (true) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (true) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (true) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
+}
+
+Value *NumberExprAST::codegen() {
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ FunctionProtos[Proto->getName()] = std::move(Proto);
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->codegen()) {
+ fprintf(stderr, "Read function definition:");
+ FnIR->dump();
+ TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (FnAST->codegen()) {
+ // JIT the module containing the anonymous expression, keeping a handle so
+ // we can free it later.
+ auto H = TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+
+ // Search the JIT for the __anon_expr symbol.
+ auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
+ assert(ExprSymbol && "Function not found");
+
+ // Get the symbol's address and cast it to the right type (takes no
+ // arguments, returns a double) so we can call it as a native function.
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
+ fprintf(stderr, "Evaluated to %f\n", FP());
+
+ // Delete the anonymous expression module from the JIT.
+ TheJIT->removeModule(H);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (true) {
+ fprintf(stderr, "ready> ");
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+ fprintf(stderr, "ready> ");
+ getNextToken();
+
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+
+ InitializeModule();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt
new file mode 100644
index 0000000000000..ea5bc05fa00a1
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ RuntimeDyld
+ ScalarOpts
+ Support
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch2
+ toy.cpp
+ )
+
+export_executable_symbols(BuildingAJIT-Ch2)
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h
new file mode 100644
index 0000000000000..30cfed6af95ec
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h
@@ -0,0 +1,133 @@
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+class KaleidoscopeJIT {
+private:
+ std::unique_ptr<TargetMachine> TM;
+ const DataLayout DL;
+ ObjectLinkingLayer<> ObjectLayer;
+ IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
+
+ typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
+ OptimizeFunction;
+
+ IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
+
+public:
+ typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
+
+ KaleidoscopeJIT()
+ : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
+ OptimizeLayer(CompileLayer,
+ [this](std::unique_ptr<Module> M) {
+ return optimizeModule(std::move(M));
+ }) {
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
+ }
+
+ TargetMachine &getTargetMachine() { return *TM; }
+
+ ModuleHandle addModule(std::unique_ptr<Module> M) {
+ // Build our symbol resolver:
+ // Lambda 1: Look back into the JIT itself to find symbols that are part of
+ // the same "logical dylib".
+ // Lambda 2: Search for external symbols in the host process.
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = OptimizeLayer.findSymbol(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ if (auto SymAddr =
+ RTDyldMemoryManager::getSymbolAddressInProcess(Name))
+ return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported);
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ // Build a singlton module set to hold our module.
+ std::vector<std::unique_ptr<Module>> Ms;
+ Ms.push_back(std::move(M));
+
+ // Add the set to the JIT with the resolver we created above and a newly
+ // created SectionMemoryManager.
+ return OptimizeLayer.addModuleSet(std::move(Ms),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
+ }
+
+ JITSymbol findSymbol(const std::string Name) {
+ std::string MangledName;
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ return OptimizeLayer.findSymbol(MangledNameStream.str(), true);
+ }
+
+ void removeModule(ModuleHandle H) {
+ OptimizeLayer.removeModuleSet(H);
+ }
+
+private:
+
+ std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
+ // Create a function pass manager.
+ auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
+
+ // Add some optimizations.
+ FPM->add(createInstructionCombiningPass());
+ FPM->add(createReassociatePass());
+ FPM->add(createGVNPass());
+ FPM->add(createCFGSimplificationPass());
+ FPM->doInitialization();
+
+ // Run the optimizations over all functions in the module being added to
+ // the JIT.
+ for (auto &F : *M)
+ FPM->run(F);
+
+ return M;
+ }
+
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter2/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter2/toy.cpp
new file mode 100644
index 0000000000000..22b0819cd71a9
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter2/toy.cpp
@@ -0,0 +1,1219 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "KaleidoscopeJIT.h"
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = getchar();
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = getchar())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = getchar();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = getchar();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = getchar();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+namespace {
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(const std::string &Name) : Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
+ Value *codegen() override;
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+
+public:
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ Function *codegen();
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (true) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (true) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (true) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
+}
+
+Value *NumberExprAST::codegen() {
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ FunctionProtos[Proto->getName()] = std::move(Proto);
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->codegen()) {
+ fprintf(stderr, "Read function definition:");
+ FnIR->dump();
+ TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (FnAST->codegen()) {
+ // JIT the module containing the anonymous expression, keeping a handle so
+ // we can free it later.
+ auto H = TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+
+ // Search the JIT for the __anon_expr symbol.
+ auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
+ assert(ExprSymbol && "Function not found");
+
+ // Get the symbol's address and cast it to the right type (takes no
+ // arguments, returns a double) so we can call it as a native function.
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
+ fprintf(stderr, "Evaluated to %f\n", FP());
+
+ // Delete the anonymous expression module from the JIT.
+ TheJIT->removeModule(H);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (true) {
+ fprintf(stderr, "ready> ");
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+ fprintf(stderr, "ready> ");
+ getNextToken();
+
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+
+ InitializeModule();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter3/CMakeLists.txt
new file mode 100644
index 0000000000000..51800a64b1e30
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ OrcJIT
+ RuntimeDyld
+ ScalarOpts
+ Support
+ TransformUtils
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch3
+ toy.cpp
+ )
+
+export_executable_symbols(BuildingAJIT-Ch3)
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h
new file mode 100644
index 0000000000000..68bdafe9897c5
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/KaleidoscopeJIT.h
@@ -0,0 +1,144 @@
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+class KaleidoscopeJIT {
+private:
+ std::unique_ptr<TargetMachine> TM;
+ const DataLayout DL;
+ ObjectLinkingLayer<> ObjectLayer;
+ IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
+
+ typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
+ OptimizeFunction;
+
+ IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
+
+ std::unique_ptr<JITCompileCallbackManager> CompileCallbackManager;
+ CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer;
+
+public:
+ typedef decltype(CODLayer)::ModuleSetHandleT ModuleHandle;
+
+ KaleidoscopeJIT()
+ : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
+ OptimizeLayer(CompileLayer,
+ [this](std::unique_ptr<Module> M) {
+ return optimizeModule(std::move(M));
+ }),
+ CompileCallbackManager(
+ orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)),
+ CODLayer(OptimizeLayer,
+ [this](Function &F) { return std::set<Function*>({&F}); },
+ *CompileCallbackManager,
+ orc::createLocalIndirectStubsManagerBuilder(
+ TM->getTargetTriple())) {
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
+ }
+
+ TargetMachine &getTargetMachine() { return *TM; }
+
+ ModuleHandle addModule(std::unique_ptr<Module> M) {
+ // Build our symbol resolver:
+ // Lambda 1: Look back into the JIT itself to find symbols that are part of
+ // the same "logical dylib".
+ // Lambda 2: Search for external symbols in the host process.
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = CODLayer.findSymbol(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ if (auto SymAddr =
+ RTDyldMemoryManager::getSymbolAddressInProcess(Name))
+ return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported);
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ // Build a singlton module set to hold our module.
+ std::vector<std::unique_ptr<Module>> Ms;
+ Ms.push_back(std::move(M));
+
+ // Add the set to the JIT with the resolver we created above and a newly
+ // created SectionMemoryManager.
+ return CODLayer.addModuleSet(std::move(Ms),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
+ }
+
+ JITSymbol findSymbol(const std::string Name) {
+ std::string MangledName;
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ return CODLayer.findSymbol(MangledNameStream.str(), true);
+ }
+
+ void removeModule(ModuleHandle H) {
+ CODLayer.removeModuleSet(H);
+ }
+
+private:
+
+ std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
+ // Create a function pass manager.
+ auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
+
+ // Add some optimizations.
+ FPM->add(createInstructionCombiningPass());
+ FPM->add(createReassociatePass());
+ FPM->add(createGVNPass());
+ FPM->add(createCFGSimplificationPass());
+ FPM->doInitialization();
+
+ // Run the optimizations over all functions in the module being added to
+ // the JIT.
+ for (auto &F : *M)
+ FPM->run(F);
+
+ return M;
+ }
+
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter3/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter3/toy.cpp
new file mode 100644
index 0000000000000..22b0819cd71a9
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter3/toy.cpp
@@ -0,0 +1,1219 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "KaleidoscopeJIT.h"
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = getchar();
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = getchar())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = getchar();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = getchar();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = getchar();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+namespace {
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(const std::string &Name) : Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
+ Value *codegen() override;
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+
+public:
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ Function *codegen();
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (true) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (true) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (true) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
+}
+
+Value *NumberExprAST::codegen() {
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ FunctionProtos[Proto->getName()] = std::move(Proto);
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->codegen()) {
+ fprintf(stderr, "Read function definition:");
+ FnIR->dump();
+ TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (FnAST->codegen()) {
+ // JIT the module containing the anonymous expression, keeping a handle so
+ // we can free it later.
+ auto H = TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+
+ // Search the JIT for the __anon_expr symbol.
+ auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
+ assert(ExprSymbol && "Function not found");
+
+ // Get the symbol's address and cast it to the right type (takes no
+ // arguments, returns a double) so we can call it as a native function.
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
+ fprintf(stderr, "Evaluated to %f\n", FP());
+
+ // Delete the anonymous expression module from the JIT.
+ TheJIT->removeModule(H);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (true) {
+ fprintf(stderr, "ready> ");
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+ fprintf(stderr, "ready> ");
+ getNextToken();
+
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+
+ InitializeModule();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter4/CMakeLists.txt
new file mode 100644
index 0000000000000..7cd40a1da60dc
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ OrcJIT
+ RuntimeDyld
+ ScalarOpts
+ Support
+ TransformUtils
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch4
+ toy.cpp
+ )
+
+export_executable_symbols(BuildingAJIT-Ch4)
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h
new file mode 100644
index 0000000000000..d14c2b1805f61
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h
@@ -0,0 +1,232 @@
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+class PrototypeAST;
+class ExprAST;
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ const PrototypeAST& getProto() const;
+ const std::string& getName() const;
+ llvm::Function *codegen();
+};
+
+/// This will compile FnAST to IR, rename the function to add the given
+/// suffix (needed to prevent a name-clash with the function's stub),
+/// and then take ownership of the module that the function was compiled
+/// into.
+std::unique_ptr<llvm::Module>
+irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix);
+
+namespace llvm {
+namespace orc {
+
+class KaleidoscopeJIT {
+private:
+ std::unique_ptr<TargetMachine> TM;
+ const DataLayout DL;
+ ObjectLinkingLayer<> ObjectLayer;
+ IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
+
+ typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
+ OptimizeFunction;
+
+ IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
+
+ std::unique_ptr<JITCompileCallbackManager> CompileCallbackMgr;
+ std::unique_ptr<IndirectStubsManager> IndirectStubsMgr;
+
+public:
+ typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
+
+ KaleidoscopeJIT()
+ : TM(EngineBuilder().selectTarget()),
+ DL(TM->createDataLayout()),
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
+ OptimizeLayer(CompileLayer,
+ [this](std::unique_ptr<Module> M) {
+ return optimizeModule(std::move(M));
+ }),
+ CompileCallbackMgr(
+ orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)) {
+ auto IndirectStubsMgrBuilder =
+ orc::createLocalIndirectStubsManagerBuilder(TM->getTargetTriple());
+ IndirectStubsMgr = IndirectStubsMgrBuilder();
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
+ }
+
+ TargetMachine &getTargetMachine() { return *TM; }
+
+ ModuleHandle addModule(std::unique_ptr<Module> M) {
+
+ // Build our symbol resolver:
+ // Lambda 1: Look back into the JIT itself to find symbols that are part of
+ // the same "logical dylib".
+ // Lambda 2: Search for external symbols in the host process.
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = IndirectStubsMgr->findStub(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ if (auto Sym = OptimizeLayer.findSymbol(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [](const std::string &Name) {
+ if (auto SymAddr =
+ RTDyldMemoryManager::getSymbolAddressInProcess(Name))
+ return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported);
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ // Build a singlton module set to hold our module.
+ std::vector<std::unique_ptr<Module>> Ms;
+ Ms.push_back(std::move(M));
+
+ // Add the set to the JIT with the resolver we created above and a newly
+ // created SectionMemoryManager.
+ return OptimizeLayer.addModuleSet(std::move(Ms),
+ make_unique<SectionMemoryManager>(),
+ std::move(Resolver));
+ }
+
+ Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
+ // Create a CompileCallback - this is the re-entry point into the compiler
+ // for functions that haven't been compiled yet.
+ auto CCInfo = CompileCallbackMgr->getCompileCallback();
+
+ // Create an indirect stub. This serves as the functions "canonical
+ // definition" - an unchanging (constant address) entry point to the
+ // function implementation.
+ // Initially we point the stub's function-pointer at the compile callback
+ // that we just created. In the compile action for the callback (see below)
+ // we will update the stub's function pointer to point at the function
+ // implementation that we just implemented.
+ if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()),
+ CCInfo.getAddress(),
+ JITSymbolFlags::Exported))
+ return Err;
+
+ // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support
+ // capture-by-move, which is be required for unique_ptr.
+ auto SharedFnAST = std::shared_ptr<FunctionAST>(std::move(FnAST));
+
+ // Set the action to compile our AST. This lambda will be run if/when
+ // execution hits the compile callback (via the stub).
+ //
+ // The steps to compile are:
+ // (1) IRGen the function.
+ // (2) Add the IR module to the JIT to make it executable like any other
+ // module.
+ // (3) Use findSymbol to get the address of the compiled function.
+ // (4) Update the stub pointer to point at the implementation so that
+ /// subsequent calls go directly to it and bypass the compiler.
+ // (5) Return the address of the implementation: this lambda will actually
+ // be run inside an attempted call to the function, and we need to
+ // continue on to the implementation to complete the attempted call.
+ // The JIT runtime (the resolver block) will use the return address of
+ // this function as the address to continue at once it has reset the
+ // CPU state to what it was immediately before the call.
+ CCInfo.setCompileAction(
+ [this, SharedFnAST]() {
+ auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl");
+ addModule(std::move(M));
+ auto Sym = findSymbol(SharedFnAST->getName() + "$impl");
+ assert(Sym && "Couldn't find compiled function?");
+ TargetAddress SymAddr = Sym.getAddress();
+ if (auto Err =
+ IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()),
+ SymAddr)) {
+ logAllUnhandledErrors(std::move(Err), errs(),
+ "Error updating function pointer: ");
+ exit(1);
+ }
+
+ return SymAddr;
+ });
+
+ return Error::success();
+ }
+
+ JITSymbol findSymbol(const std::string Name) {
+ return OptimizeLayer.findSymbol(mangle(Name), true);
+ }
+
+ void removeModule(ModuleHandle H) {
+ OptimizeLayer.removeModuleSet(H);
+ }
+
+private:
+
+ std::string mangle(const std::string &Name) {
+ std::string MangledName;
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ return MangledNameStream.str();
+ }
+
+ std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
+ // Create a function pass manager.
+ auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
+
+ // Add some optimizations.
+ FPM->add(createInstructionCombiningPass());
+ FPM->add(createReassociatePass());
+ FPM->add(createGVNPass());
+ FPM->add(createCFGSimplificationPass());
+ FPM->doInitialization();
+
+ // Run the optimizations over all functions in the module being added to
+ // the JIT.
+ for (auto &F : *M)
+ FPM->run(F);
+
+ return M;
+ }
+
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter4/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter4/toy.cpp
new file mode 100644
index 0000000000000..ddce0dc35b25c
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter4/toy.cpp
@@ -0,0 +1,1228 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "KaleidoscopeJIT.h"
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = getchar();
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = getchar())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = getchar();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = getchar();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = getchar();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(const std::string &Name) : Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
+ Value *codegen() override;
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+
+public:
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+};
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (true) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (true) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (true) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+static ExitOnError ExitOnErr;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
+}
+
+Value *NumberExprAST::codegen() {
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+const PrototypeAST& FunctionAST::getProto() const {
+ return *Proto;
+}
+
+const std::string& FunctionAST::getName() const {
+ return Proto->getName();
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+std::unique_ptr<llvm::Module>
+irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix) {
+ if (auto *F = FnAST.codegen()) {
+ F->setName(F->getName() + Suffix);
+ auto M = std::move(TheModule);
+ // Start a new module.
+ InitializeModule();
+ return M;
+ } else
+ report_fatal_error("Couldn't compile lazily JIT'd function");
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ FunctionProtos[FnAST->getProto().getName()] =
+ llvm::make_unique<PrototypeAST>(FnAST->getProto());
+ ExitOnErr(TheJIT->addFunctionAST(std::move(FnAST)));
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ FunctionProtos[FnAST->getName()] =
+ llvm::make_unique<PrototypeAST>(FnAST->getProto());
+ if (FnAST->codegen()) {
+ // JIT the module containing the anonymous expression, keeping a handle so
+ // we can free it later.
+ auto H = TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+
+ // Search the JIT for the __anon_expr symbol.
+ auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
+ assert(ExprSymbol && "Function not found");
+
+ // Get the symbol's address and cast it to the right type (takes no
+ // arguments, returns a double) so we can call it as a native function.
+ double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
+ fprintf(stderr, "Evaluated to %f\n", FP());
+
+ // Delete the anonymous expression module from the JIT.
+ TheJIT->removeModule(H);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (true) {
+ fprintf(stderr, "ready> ");
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ ExitOnErr.setBanner("Kaleidoscope: ");
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+ fprintf(stderr, "ready> ");
+ getNextToken();
+
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+
+ InitializeModule();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter5/CMakeLists.txt
new file mode 100644
index 0000000000000..d5b832b495504
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_subdirectory(Server)
+
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ OrcJIT
+ RuntimeDyld
+ ScalarOpts
+ Support
+ TransformUtils
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch5
+ toy.cpp
+ )
+
+export_executable_symbols(BuildingAJIT-Ch5)
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h
new file mode 100644
index 0000000000000..24d6dc9b7b8f0
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h
@@ -0,0 +1,264 @@
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+
+#include "RemoteJITUtils.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+class PrototypeAST;
+class ExprAST;
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ const PrototypeAST& getProto() const;
+ const std::string& getName() const;
+ llvm::Function *codegen();
+};
+
+/// This will compile FnAST to IR, rename the function to add the given
+/// suffix (needed to prevent a name-clash with the function's stub),
+/// and then take ownership of the module that the function was compiled
+/// into.
+std::unique_ptr<llvm::Module>
+irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix);
+
+namespace llvm {
+namespace orc {
+
+// Typedef the remote-client API.
+typedef remote::OrcRemoteTargetClient<FDRPCChannel> MyRemote;
+
+class KaleidoscopeJIT {
+private:
+ std::unique_ptr<TargetMachine> TM;
+ const DataLayout DL;
+ ObjectLinkingLayer<> ObjectLayer;
+ IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
+
+ typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
+ OptimizeFunction;
+
+ IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
+
+ JITCompileCallbackManager *CompileCallbackMgr;
+ std::unique_ptr<IndirectStubsManager> IndirectStubsMgr;
+ MyRemote &Remote;
+
+public:
+ typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
+
+ KaleidoscopeJIT(MyRemote &Remote)
+ : TM(EngineBuilder().selectTarget()),
+ DL(TM->createDataLayout()),
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
+ OptimizeLayer(CompileLayer,
+ [this](std::unique_ptr<Module> M) {
+ return optimizeModule(std::move(M));
+ }),
+ Remote(Remote) {
+ auto CCMgrOrErr = Remote.enableCompileCallbacks(0);
+ if (!CCMgrOrErr) {
+ logAllUnhandledErrors(CCMgrOrErr.takeError(), errs(),
+ "Error enabling remote compile callbacks:");
+ exit(1);
+ }
+ CompileCallbackMgr = &*CCMgrOrErr;
+ std::unique_ptr<MyRemote::RCIndirectStubsManager> ISM;
+ if (auto Err = Remote.createIndirectStubsManager(ISM)) {
+ logAllUnhandledErrors(std::move(Err), errs(),
+ "Error creating indirect stubs manager:");
+ exit(1);
+ }
+ IndirectStubsMgr = std::move(ISM);
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
+ }
+
+ TargetMachine &getTargetMachine() { return *TM; }
+
+ ModuleHandle addModule(std::unique_ptr<Module> M) {
+
+ // Build our symbol resolver:
+ // Lambda 1: Look back into the JIT itself to find symbols that are part of
+ // the same "logical dylib".
+ // Lambda 2: Search for external symbols in the host process.
+ auto Resolver = createLambdaResolver(
+ [&](const std::string &Name) {
+ if (auto Sym = IndirectStubsMgr->findStub(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ if (auto Sym = OptimizeLayer.findSymbol(Name, false))
+ return Sym.toRuntimeDyldSymbol();
+ return RuntimeDyld::SymbolInfo(nullptr);
+ },
+ [&](const std::string &Name) {
+ if (auto AddrOrErr = Remote.getSymbolAddress(Name))
+ return RuntimeDyld::SymbolInfo(*AddrOrErr,
+ JITSymbolFlags::Exported);
+ else {
+ logAllUnhandledErrors(AddrOrErr.takeError(), errs(),
+ "Error resolving remote symbol:");
+ exit(1);
+ }
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+
+ std::unique_ptr<MyRemote::RCMemoryManager> MemMgr;
+ if (auto Err = Remote.createRemoteMemoryManager(MemMgr)) {
+ logAllUnhandledErrors(std::move(Err), errs(),
+ "Error creating remote memory manager:");
+ exit(1);
+ }
+
+ // Build a singlton module set to hold our module.
+ std::vector<std::unique_ptr<Module>> Ms;
+ Ms.push_back(std::move(M));
+
+ // Add the set to the JIT with the resolver we created above and a newly
+ // created SectionMemoryManager.
+ return OptimizeLayer.addModuleSet(std::move(Ms),
+ std::move(MemMgr),
+ std::move(Resolver));
+ }
+
+ Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
+ // Create a CompileCallback - this is the re-entry point into the compiler
+ // for functions that haven't been compiled yet.
+ auto CCInfo = CompileCallbackMgr->getCompileCallback();
+
+ // Create an indirect stub. This serves as the functions "canonical
+ // definition" - an unchanging (constant address) entry point to the
+ // function implementation.
+ // Initially we point the stub's function-pointer at the compile callback
+ // that we just created. In the compile action for the callback (see below)
+ // we will update the stub's function pointer to point at the function
+ // implementation that we just implemented.
+ if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()),
+ CCInfo.getAddress(),
+ JITSymbolFlags::Exported))
+ return Err;
+
+ // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support
+ // capture-by-move, which is be required for unique_ptr.
+ auto SharedFnAST = std::shared_ptr<FunctionAST>(std::move(FnAST));
+
+ // Set the action to compile our AST. This lambda will be run if/when
+ // execution hits the compile callback (via the stub).
+ //
+ // The steps to compile are:
+ // (1) IRGen the function.
+ // (2) Add the IR module to the JIT to make it executable like any other
+ // module.
+ // (3) Use findSymbol to get the address of the compiled function.
+ // (4) Update the stub pointer to point at the implementation so that
+ /// subsequent calls go directly to it and bypass the compiler.
+ // (5) Return the address of the implementation: this lambda will actually
+ // be run inside an attempted call to the function, and we need to
+ // continue on to the implementation to complete the attempted call.
+ // The JIT runtime (the resolver block) will use the return address of
+ // this function as the address to continue at once it has reset the
+ // CPU state to what it was immediately before the call.
+ CCInfo.setCompileAction(
+ [this, SharedFnAST]() {
+ auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl");
+ addModule(std::move(M));
+ auto Sym = findSymbol(SharedFnAST->getName() + "$impl");
+ assert(Sym && "Couldn't find compiled function?");
+ TargetAddress SymAddr = Sym.getAddress();
+ if (auto Err =
+ IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()),
+ SymAddr)) {
+ logAllUnhandledErrors(std::move(Err), errs(),
+ "Error updating function pointer: ");
+ exit(1);
+ }
+
+ return SymAddr;
+ });
+
+ return Error::success();
+ }
+
+ Error executeRemoteExpr(TargetAddress ExprAddr) {
+ return Remote.callVoidVoid(ExprAddr);
+ }
+
+ JITSymbol findSymbol(const std::string Name) {
+ return OptimizeLayer.findSymbol(mangle(Name), true);
+ }
+
+ void removeModule(ModuleHandle H) {
+ OptimizeLayer.removeModuleSet(H);
+ }
+
+private:
+
+ std::string mangle(const std::string &Name) {
+ std::string MangledName;
+ raw_string_ostream MangledNameStream(MangledName);
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
+ return MangledNameStream.str();
+ }
+
+ std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
+ // Create a function pass manager.
+ auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
+
+ // Add some optimizations.
+ FPM->add(createInstructionCombiningPass());
+ FPM->add(createReassociatePass());
+ FPM->add(createGVNPass());
+ FPM->add(createCFGSimplificationPass());
+ FPM->doInitialization();
+
+ // Run the optimizations over all functions in the module being added to
+ // the JIT.
+ for (auto &F : *M)
+ FPM->run(F);
+
+ return M;
+ }
+
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/RemoteJITUtils.h b/examples/Kaleidoscope/BuildingAJIT/Chapter5/RemoteJITUtils.h
new file mode 100644
index 0000000000000..869d0a7ef39da
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/RemoteJITUtils.h
@@ -0,0 +1,74 @@
+//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for remote-JITing with LLI.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H
+#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H
+
+#include "llvm/ExecutionEngine/Orc/RPCChannel.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include <mutex>
+
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+/// RPC channel that reads from and writes from file descriptors.
+class FDRPCChannel final : public llvm::orc::remote::RPCChannel {
+public:
+ FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
+
+ llvm::Error readBytes(char *Dst, unsigned Size) override {
+ assert(Dst && "Attempt to read into null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
+ if (Read <= 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Read;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error appendBytes(const char *Src, unsigned Size) override {
+ assert(Src && "Attempt to append from null.");
+ ssize_t Completed = 0;
+ while (Completed < static_cast<ssize_t>(Size)) {
+ ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
+ if (Written < 0) {
+ auto ErrNo = errno;
+ if (ErrNo == EAGAIN || ErrNo == EINTR)
+ continue;
+ else
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ Completed += Written;
+ }
+ return llvm::Error::success();
+ }
+
+ llvm::Error send() override { return llvm::Error::success(); }
+
+private:
+ int InFD, OutFD;
+};
+
+#endif
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/CMakeLists.txt b/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/CMakeLists.txt
new file mode 100644
index 0000000000000..15dd53516ceb0
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_LINK_COMPONENTS
+ Analysis
+ Core
+ ExecutionEngine
+ InstCombine
+ Object
+ OrcJIT
+ RuntimeDyld
+ ScalarOpts
+ Support
+ TransformUtils
+ native
+ )
+
+add_kaleidoscope_chapter(BuildingAJIT-Ch5-Server
+ server.cpp
+ )
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/server.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/server.cpp
new file mode 100644
index 0000000000000..c53e22fe83ae2
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/Server/server.cpp
@@ -0,0 +1,119 @@
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"
+#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
+
+#include "../RemoteJITUtils.h"
+
+#include <cstring>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+
+using namespace llvm;
+using namespace llvm::orc;
+
+// Command line argument for TCP port.
+cl::opt<uint32_t> Port("port",
+ cl::desc("TCP port to listen on"),
+ cl::init(20000));
+
+ExitOnError ExitOnErr;
+
+typedef int (*MainFun)(int, const char*[]);
+
+template <typename NativePtrT>
+NativePtrT MakeNative(uint64_t P) {
+ return reinterpret_cast<NativePtrT>(static_cast<uintptr_t>(P));
+}
+
+extern "C"
+void printExprResult(double Val) {
+ printf("Expression evaluated to: %f\n", Val);
+}
+
+// --- LAZY COMPILE TEST ---
+int main(int argc, char* argv[]) {
+
+ if (argc == 0)
+ ExitOnErr.setBanner("jit_server: ");
+ else
+ ExitOnErr.setBanner(std::string(argv[0]) + ": ");
+
+ // --- Initialize LLVM ---
+ cl::ParseCommandLineOptions(argc, argv, "LLVM lazy JIT example.\n");
+
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
+ errs() << "Error loading program symbols.\n";
+ return 1;
+ }
+
+ // --- Initialize remote connection ---
+
+ int sockfd = socket(PF_INET, SOCK_STREAM, 0);
+ sockaddr_in servAddr, clientAddr;
+ socklen_t clientAddrLen = sizeof(clientAddr);
+ bzero(&servAddr, sizeof(servAddr));
+ servAddr.sin_family = PF_INET;
+ servAddr.sin_family = INADDR_ANY;
+ servAddr.sin_port = htons(Port);
+
+ {
+ // avoid "Address already in use" error.
+ int yes=1;
+ if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+ errs() << "Error calling setsockopt.\n";
+ return 1;
+ }
+ }
+
+ if (bind(sockfd, reinterpret_cast<sockaddr*>(&servAddr),
+ sizeof(servAddr)) < 0) {
+ errs() << "Error on binding.\n";
+ return 1;
+ }
+ listen(sockfd, 1);
+ int newsockfd = accept(sockfd, reinterpret_cast<sockaddr*>(&clientAddr),
+ &clientAddrLen);
+
+ auto SymbolLookup =
+ [](const std::string &Name) {
+ return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
+ };
+
+ auto RegisterEHFrames =
+ [](uint8_t *Addr, uint32_t Size) {
+ RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size);
+ };
+
+ auto DeregisterEHFrames =
+ [](uint8_t *Addr, uint32_t Size) {
+ RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size);
+ };
+
+ FDRPCChannel TCPChannel(newsockfd, newsockfd);
+ typedef remote::OrcRemoteTargetServer<FDRPCChannel, OrcX86_64_SysV> MyServerT;
+
+ MyServerT Server(TCPChannel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames);
+
+ while (1) {
+ MyServerT::JITFuncId Id = MyServerT::InvalidId;
+ ExitOnErr(Server.startReceivingFunction(TCPChannel, (uint32_t&)Id));
+ switch (Id) {
+ case MyServerT::TerminateSessionId:
+ ExitOnErr(Server.handleTerminateSession());
+ return 0;
+ default:
+ ExitOnErr(Server.handleKnownFunction(Id));
+ break;
+ }
+ }
+
+ llvm_unreachable("Fell through server command loop.");
+}
diff --git a/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp b/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp
new file mode 100644
index 0000000000000..9c21098971a68
--- /dev/null
+++ b/examples/Kaleidoscope/BuildingAJIT/Chapter5/toy.cpp
@@ -0,0 +1,1294 @@
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "KaleidoscopeJIT.h"
+#include <cassert>
+#include <cctype>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <netdb.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+// Command line argument for TCP hostname.
+cl::opt<std::string> HostName("hostname",
+ cl::desc("TCP hostname to connect to"),
+ cl::init("localhost"));
+
+// Command line argument for TCP port.
+cl::opt<uint32_t> Port("port",
+ cl::desc("TCP port to connect to"),
+ cl::init(20000));
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = getchar();
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = getchar())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = getchar();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = getchar();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = getchar();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(const std::string &Name) : Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
+ Value *codegen() override;
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+
+public:
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+};
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (true) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (true) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (true) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
+
+ auto PEArgs = std::vector<std::unique_ptr<ExprAST>>();
+ PEArgs.push_back(std::move(E));
+ auto PrintExpr =
+ llvm::make_unique<CallExprAST>("printExprResult", std::move(PEArgs));
+
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto),
+ std::move(PrintExpr));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+static ExitOnError ExitOnErr;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
+}
+
+Value *NumberExprAST::codegen() {
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+const PrototypeAST& FunctionAST::getProto() const {
+ return *Proto;
+}
+
+const std::string& FunctionAST::getName() const {
+ return Proto->getName();
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+std::unique_ptr<llvm::Module>
+irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix) {
+ if (auto *F = FnAST.codegen()) {
+ F->setName(F->getName() + Suffix);
+ auto M = std::move(TheModule);
+ // Start a new module.
+ InitializeModule();
+ return M;
+ } else
+ report_fatal_error("Couldn't compile lazily JIT'd function");
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ FunctionProtos[FnAST->getProto().getName()] =
+ llvm::make_unique<PrototypeAST>(FnAST->getProto());
+ ExitOnErr(TheJIT->addFunctionAST(std::move(FnAST)));
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ FunctionProtos[FnAST->getName()] =
+ llvm::make_unique<PrototypeAST>(FnAST->getProto());
+ if (FnAST->codegen()) {
+ // JIT the module containing the anonymous expression, keeping a handle so
+ // we can free it later.
+ auto H = TheJIT->addModule(std::move(TheModule));
+ InitializeModule();
+
+ // Search the JIT for the __anon_expr symbol.
+ auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
+ assert(ExprSymbol && "Function not found");
+
+ // Get the symbol's address and cast it to the right type (takes no
+ // arguments, returns a double) so we can call it as a native function.
+ ExitOnErr(TheJIT->executeRemoteExpr(ExprSymbol.getAddress()));
+
+ // Delete the anonymous expression module from the JIT.
+ TheJIT->removeModule(H);
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (true) {
+ fprintf(stderr, "ready> ");
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// TCP / Connection setup code.
+//===----------------------------------------------------------------------===//
+
+std::unique_ptr<FDRPCChannel> connect() {
+ int sockfd = socket(PF_INET, SOCK_STREAM, 0);
+ hostent *server = gethostbyname(HostName.c_str());
+
+ if (!server) {
+ errs() << "Could not find host " << HostName << "\n";
+ exit(1);
+ }
+
+ sockaddr_in servAddr;
+ bzero(&servAddr, sizeof(servAddr));
+ servAddr.sin_family = PF_INET;
+ bcopy(server->h_addr, &servAddr.sin_addr.s_addr, server->h_length);
+ servAddr.sin_port = htons(Port);
+ if (connect(sockfd, reinterpret_cast<sockaddr*>(&servAddr),
+ sizeof(servAddr)) < 0) {
+ errs() << "Failure to connect.\n";
+ exit(1);
+ }
+
+ return llvm::make_unique<FDRPCChannel>(sockfd, sockfd);
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main(int argc, char *argv[]) {
+ // Parse the command line options.
+ cl::ParseCommandLineOptions(argc, argv, "Building A JIT - Client.\n");
+
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ ExitOnErr.setBanner("Kaleidoscope: ");
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ auto TCPChannel = connect();
+ MyRemote Remote = ExitOnErr(MyRemote::Create(*TCPChannel));
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>(Remote);
+
+ // Automatically inject a definition for 'printExprResult'.
+ FunctionProtos["printExprResult"] =
+ llvm::make_unique<PrototypeAST>("printExprResult",
+ std::vector<std::string>({"Val"}));
+
+ // Prime the first token.
+ fprintf(stderr, "ready> ");
+ getNextToken();
+
+ InitializeModule();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ // Delete the JIT before the Remote and Channel go out of scope, otherwise
+ // we'll crash in the JIT destructor when it tries to release remote
+ // resources over a channel that no longer exists.
+ TheJIT = nullptr;
+
+ // Send a terminate message to the remote to tell it to exit cleanly.
+ ExitOnErr(Remote.terminateSession());
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/CMakeLists.txt b/examples/Kaleidoscope/CMakeLists.txt
index 32664aa2a2272..543b9f73b4fe2 100644
--- a/examples/Kaleidoscope/CMakeLists.txt
+++ b/examples/Kaleidoscope/CMakeLists.txt
@@ -6,6 +6,7 @@ macro(add_kaleidoscope_chapter name)
add_llvm_example(${name} ${ARGN})
endmacro(add_kaleidoscope_chapter name)
+add_subdirectory(BuildingAJIT)
add_subdirectory(Chapter2)
add_subdirectory(Chapter3)
add_subdirectory(Chapter4)
@@ -13,4 +14,3 @@ add_subdirectory(Chapter5)
add_subdirectory(Chapter6)
add_subdirectory(Chapter7)
add_subdirectory(Chapter8)
-add_subdirectory(Orc)
diff --git a/examples/Kaleidoscope/Chapter2/Makefile b/examples/Kaleidoscope/Chapter2/Makefile
deleted file mode 100644
index fa27e6e06687f..0000000000000
--- a/examples/Kaleidoscope/Chapter2/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter2/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch2
-EXAMPLE_TOOL = 1
-
-LLVM_CXXFLAGS := -Wno-unused-private-field
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter2/toy.cpp b/examples/Kaleidoscope/Chapter2/toy.cpp
index 69f359961293c..31a998faadc74 100644
--- a/examples/Kaleidoscope/Chapter2/toy.cpp
+++ b/examples/Kaleidoscope/Chapter2/toy.cpp
@@ -1,5 +1,6 @@
#include <cctype>
#include <cstdio>
+#include <cstdlib>
#include <map>
#include <memory>
#include <string>
@@ -15,7 +16,7 @@ static
make_unique(Args &&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
-}
+} // end namespace helper
//===----------------------------------------------------------------------===//
// Lexer
@@ -187,13 +188,13 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -214,7 +215,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -234,7 +235,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -244,7 +245,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -262,7 +263,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -277,7 +278,7 @@ static std::unique_ptr<ExprAST> ParsePrimary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -324,19 +325,19 @@ static std::unique_ptr<ExprAST> ParseExpression() {
/// ::= id '(' id* ')'
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
@@ -407,7 +408,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
diff --git a/examples/Kaleidoscope/Chapter3/Makefile b/examples/Kaleidoscope/Chapter3/Makefile
deleted file mode 100644
index 4cc6948d80374..0000000000000
--- a/examples/Kaleidoscope/Chapter3/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter3/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch3
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter3/toy.cpp b/examples/Kaleidoscope/Chapter3/toy.cpp
index 05697ea70a490..cdf0d6c8cdb2b 100644
--- a/examples/Kaleidoscope/Chapter3/toy.cpp
+++ b/examples/Kaleidoscope/Chapter3/toy.cpp
@@ -1,11 +1,19 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include <cctype>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
#include <vector>
@@ -189,14 +197,14 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -217,7 +225,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -237,7 +245,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -247,7 +255,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -265,7 +273,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -280,7 +288,7 @@ static std::unique_ptr<ExprAST> ParsePrimary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -327,19 +335,19 @@ static std::unique_ptr<ExprAST> ParseExpression() {
/// ::= id '(' id* ')'
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
@@ -380,24 +388,25 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
-static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value *> NamedValues;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
return V;
}
@@ -417,10 +426,9 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
- return ErrorV("invalid binary operator");
+ return LogErrorV("invalid binary operator");
}
}
@@ -428,11 +436,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -446,10 +454,9 @@ Value *CallExprAST::codegen() {
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -473,7 +480,7 @@ Function *FunctionAST::codegen() {
return nullptr;
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -539,7 +546,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
@@ -577,7 +584,7 @@ int main() {
getNextToken();
// Make the module, which holds all the code.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
// Run the main "interpreter loop" now.
MainLoop();
diff --git a/examples/Kaleidoscope/Chapter4/Makefile b/examples/Kaleidoscope/Chapter4/Makefile
deleted file mode 100644
index 6d6a6706fff3e..0000000000000
--- a/examples/Kaleidoscope/Chapter4/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter4/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch4
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core mcjit native
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp
index 4f77ec862b1b9..836a2053cbe9f 100644
--- a/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -1,18 +1,29 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "../include/KaleidoscopeJIT.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
using namespace llvm::orc;
@@ -195,14 +206,14 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -223,7 +234,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -243,7 +254,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -253,7 +264,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -271,7 +282,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -286,7 +297,7 @@ static std::unique_ptr<ExprAST> ParsePrimary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -333,19 +344,19 @@ static std::unique_ptr<ExprAST> ParseExpression() {
/// ::= id '(' id* ')'
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
@@ -386,15 +397,16 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
-static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value *> NamedValues;
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -414,14 +426,14 @@ Function *getFunction(std::string Name) {
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
return V;
}
@@ -441,10 +453,9 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
- return ErrorV("invalid binary operator");
+ return LogErrorV("invalid binary operator");
}
}
@@ -452,11 +463,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -470,10 +481,9 @@ Value *CallExprAST::codegen() {
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -496,7 +506,7 @@ Function *FunctionAST::codegen() {
return nullptr;
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -528,7 +538,7 @@ Function *FunctionAST::codegen() {
static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
// Create a new pass manager attached to it.
@@ -577,7 +587,6 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
if (FnAST->codegen()) {
-
// JIT the module containing the anonymous expression, keeping a handle so
// we can free it later.
auto H = TheJIT->addModule(std::move(TheModule));
@@ -603,7 +612,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
diff --git a/examples/Kaleidoscope/Chapter5/Makefile b/examples/Kaleidoscope/Chapter5/Makefile
deleted file mode 100644
index d7809672303e8..0000000000000
--- a/examples/Kaleidoscope/Chapter5/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter5/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch5
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core mcjit native
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp
index eeca4775eeb11..a080bd00cb580 100644
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -1,18 +1,30 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "../include/KaleidoscopeJIT.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
using namespace llvm::orc;
@@ -237,14 +249,14 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -265,7 +277,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -285,7 +297,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -295,7 +307,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -316,7 +328,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_then)
- return Error("expected then");
+ return LogError("expected then");
getNextToken(); // eat the then
auto Then = ParseExpression();
@@ -324,7 +336,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_else)
- return Error("expected else");
+ return LogError("expected else");
getNextToken();
@@ -341,20 +353,20 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
- return Error("expected identifier after for");
+ return LogError("expected identifier after for");
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '=')
- return Error("expected '=' after for");
+ return LogError("expected '=' after for");
getNextToken(); // eat '='.
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
- return Error("expected ',' after for start value");
+ return LogError("expected ',' after for start value");
getNextToken();
auto End = ParseExpression();
@@ -371,7 +383,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
}
if (CurTok != tok_in)
- return Error("expected 'in' after for");
+ return LogError("expected 'in' after for");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -391,7 +403,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -410,7 +422,7 @@ static std::unique_ptr<ExprAST> ParsePrimary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -457,19 +469,19 @@ static std::unique_ptr<ExprAST> ParseExpression() {
/// ::= id '(' id* ')'
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
@@ -510,15 +522,16 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
-static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value *> NamedValues;
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -538,14 +551,14 @@ Function *getFunction(std::string Name) {
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
return V;
}
@@ -565,10 +578,9 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
- return ErrorV("invalid binary operator");
+ return LogErrorV("invalid binary operator");
}
}
@@ -576,11 +588,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -599,16 +611,15 @@ Value *IfExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
- CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB =
- BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -638,8 +649,7 @@ Value *IfExprAST::codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN =
- Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -671,8 +681,7 @@ Value *ForExprAST::codegen() {
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
- BasicBlock *LoopBB =
- BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -681,8 +690,8 @@ Value *ForExprAST::codegen() {
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
- PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
- 2, VarName.c_str());
+ PHINode *Variable =
+ Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName);
Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to the PHI node. If it
@@ -704,7 +713,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar");
@@ -716,12 +725,12 @@ Value *ForExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
- EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
BasicBlock *AfterBB =
- BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -739,15 +748,14 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -770,7 +778,7 @@ Function *FunctionAST::codegen() {
return nullptr;
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -802,7 +810,7 @@ Function *FunctionAST::codegen() {
static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
// Create a new pass manager attached to it.
@@ -851,7 +859,6 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
if (FnAST->codegen()) {
-
// JIT the module containing the anonymous expression, keeping a handle so
// we can free it later.
auto H = TheJIT->addModule(std::move(TheModule));
@@ -877,7 +884,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
diff --git a/examples/Kaleidoscope/Chapter6/Makefile b/examples/Kaleidoscope/Chapter6/Makefile
deleted file mode 100644
index 8f47ea0d98e79..0000000000000
--- a/examples/Kaleidoscope/Chapter6/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter6/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch6
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core mcjit native
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index 4d04f7e888af5..85d953b0c7564 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -1,18 +1,30 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "../include/KaleidoscopeJIT.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
using namespace llvm::orc;
@@ -271,13 +283,13 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -298,7 +310,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -318,7 +330,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -328,7 +340,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -349,7 +361,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_then)
- return Error("expected then");
+ return LogError("expected then");
getNextToken(); // eat the then
auto Then = ParseExpression();
@@ -357,7 +369,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_else)
- return Error("expected else");
+ return LogError("expected else");
getNextToken();
@@ -374,20 +386,20 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
- return Error("expected identifier after for");
+ return LogError("expected identifier after for");
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '=')
- return Error("expected '=' after for");
+ return LogError("expected '=' after for");
getNextToken(); // eat '='.
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
- return Error("expected ',' after for start value");
+ return LogError("expected ',' after for start value");
getNextToken();
auto End = ParseExpression();
@@ -404,7 +416,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
}
if (CurTok != tok_in)
- return Error("expected 'in' after for");
+ return LogError("expected 'in' after for");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -424,7 +436,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -459,7 +471,7 @@ static std::unique_ptr<ExprAST> ParseUnary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -514,7 +526,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
switch (CurTok) {
default:
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
case tok_identifier:
FnName = IdentifierStr;
Kind = 0;
@@ -523,7 +535,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_unary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected unary operator");
+ return LogErrorP("Expected unary operator");
FnName = "unary";
FnName += (char)CurTok;
Kind = 1;
@@ -532,7 +544,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_binary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected binary operator");
+ return LogErrorP("Expected binary operator");
FnName = "binary";
FnName += (char)CurTok;
Kind = 2;
@@ -541,7 +553,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return ErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedecnce: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -549,20 +561,20 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
}
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
// Verify right number of names for operator.
if (Kind && ArgNames.size() != Kind)
- return ErrorP("Invalid number of operands for operator");
+ return LogErrorP("Invalid number of operands for operator");
return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
@@ -601,15 +613,16 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
-static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value *> NamedValues;
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -629,14 +642,14 @@ Function *getFunction(std::string Name) {
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
return V;
}
@@ -647,7 +660,7 @@ Value *UnaryExprAST::codegen() {
Function *F = getFunction(std::string("unary") + Opcode);
if (!F)
- return ErrorV("Unknown unary operator");
+ return LogErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
}
@@ -668,8 +681,7 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
break;
}
@@ -687,11 +699,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -710,16 +722,15 @@ Value *IfExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
- CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB =
- BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -749,8 +760,7 @@ Value *IfExprAST::codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN =
- Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -782,8 +792,7 @@ Value *ForExprAST::codegen() {
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
- BasicBlock *LoopBB =
- BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -792,8 +801,8 @@ Value *ForExprAST::codegen() {
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
- PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
- 2, VarName.c_str());
+ PHINode *Variable =
+ Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName);
Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to the PHI node. If it
@@ -815,7 +824,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar");
@@ -827,12 +836,12 @@ Value *ForExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
- EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
BasicBlock *AfterBB =
- BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -850,15 +859,14 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -885,7 +893,7 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -920,7 +928,7 @@ Function *FunctionAST::codegen() {
static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
// Create a new pass manager attached to it.
@@ -969,7 +977,6 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
if (FnAST->codegen()) {
-
// JIT the module containing the anonymous expression, keeping a handle so
// we can free it later.
auto H = TheJIT->addModule(std::move(TheModule));
@@ -995,7 +1002,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
diff --git a/examples/Kaleidoscope/Chapter7/Makefile b/examples/Kaleidoscope/Chapter7/Makefile
deleted file mode 100644
index c672c0a36c63f..0000000000000
--- a/examples/Kaleidoscope/Chapter7/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter7/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch7
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core mcjit native
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp
index 5c0094013d975..3206ca8c5d7be 100644
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -1,18 +1,31 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "../include/KaleidoscopeJIT.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
using namespace llvm::orc;
@@ -289,14 +302,14 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -317,7 +330,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -337,7 +350,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -347,7 +360,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -368,7 +381,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_then)
- return Error("expected then");
+ return LogError("expected then");
getNextToken(); // eat the then
auto Then = ParseExpression();
@@ -376,7 +389,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_else)
- return Error("expected else");
+ return LogError("expected else");
getNextToken();
@@ -393,20 +406,20 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
- return Error("expected identifier after for");
+ return LogError("expected identifier after for");
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '=')
- return Error("expected '=' after for");
+ return LogError("expected '=' after for");
getNextToken(); // eat '='.
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
- return Error("expected ',' after for start value");
+ return LogError("expected ',' after for start value");
getNextToken();
auto End = ParseExpression();
@@ -423,7 +436,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
}
if (CurTok != tok_in)
- return Error("expected 'in' after for");
+ return LogError("expected 'in' after for");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -443,9 +456,9 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
// At least one variable name is required.
if (CurTok != tok_identifier)
- return Error("expected identifier after var");
+ return LogError("expected identifier after var");
- while (1) {
+ while (true) {
std::string Name = IdentifierStr;
getNextToken(); // eat identifier.
@@ -467,12 +480,12 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the ','.
if (CurTok != tok_identifier)
- return Error("expected identifier list after var");
+ return LogError("expected identifier list after var");
}
// At this point, we have to have 'in'.
if (CurTok != tok_in)
- return Error("expected 'in' keyword after 'var'");
+ return LogError("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -492,7 +505,7 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -529,7 +542,7 @@ static std::unique_ptr<ExprAST> ParseUnary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -584,7 +597,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
switch (CurTok) {
default:
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
case tok_identifier:
FnName = IdentifierStr;
Kind = 0;
@@ -593,7 +606,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_unary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected unary operator");
+ return LogErrorP("Expected unary operator");
FnName = "unary";
FnName += (char)CurTok;
Kind = 1;
@@ -602,7 +615,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_binary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected binary operator");
+ return LogErrorP("Expected binary operator");
FnName = "binary";
FnName += (char)CurTok;
Kind = 2;
@@ -611,7 +624,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return ErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedecnce: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -619,20 +632,20 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
}
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
// Verify right number of names for operator.
if (Kind && ArgNames.size() != Kind)
- return ErrorP("Invalid number of operands for operator");
+ return LogErrorP("Invalid number of operands for operator");
return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
@@ -671,15 +684,16 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
-static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, AllocaInst *> NamedValues;
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -704,19 +718,18 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
// Load the value.
return Builder.CreateLoad(V, Name.c_str());
@@ -729,7 +742,7 @@ Value *UnaryExprAST::codegen() {
Function *F = getFunction(std::string("unary") + Opcode);
if (!F)
- return ErrorV("Unknown unary operator");
+ return LogErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
}
@@ -743,7 +756,7 @@ Value *BinaryExprAST::codegen() {
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
if (!LHSE)
- return ErrorV("destination of '=' must be a variable");
+ return LogErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->codegen();
if (!Val)
@@ -752,7 +765,7 @@ Value *BinaryExprAST::codegen() {
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
if (!Variable)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
return Val;
@@ -773,8 +786,7 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
break;
}
@@ -792,11 +804,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -815,16 +827,15 @@ Value *IfExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
- CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB =
- BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -854,8 +865,7 @@ Value *IfExprAST::codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN =
- Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -897,8 +907,7 @@ Value *ForExprAST::codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB =
- BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -925,7 +934,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -941,11 +950,11 @@ Value *ForExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
- EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
- BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -960,7 +969,7 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::codegen() {
@@ -984,7 +993,7 @@ Value *VarExprAST::codegen() {
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1013,10 +1022,9 @@ Value *VarExprAST::codegen() {
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -1043,7 +1051,7 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -1086,7 +1094,7 @@ Function *FunctionAST::codegen() {
static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
// Create a new pass manager attached to it.
@@ -1135,7 +1143,6 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
if (FnAST->codegen()) {
-
// JIT the module containing the anonymous expression, keeping a handle so
// we can free it later.
auto H = TheJIT->addModule(std::move(TheModule));
@@ -1161,7 +1168,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
diff --git a/examples/Kaleidoscope/Chapter8/CMakeLists.txt b/examples/Kaleidoscope/Chapter8/CMakeLists.txt
index d9b5cc421be39..1bb1cd25af72d 100644
--- a/examples/Kaleidoscope/Chapter8/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter8/CMakeLists.txt
@@ -1,9 +1,5 @@
set(LLVM_LINK_COMPONENTS
- Core
- ExecutionEngine
- Object
- Support
- native
+ all
)
add_kaleidoscope_chapter(Kaleidoscope-Ch8
diff --git a/examples/Kaleidoscope/Chapter8/Makefile b/examples/Kaleidoscope/Chapter8/Makefile
deleted file mode 100644
index 25f048c39b0a4..0000000000000
--- a/examples/Kaleidoscope/Chapter8/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Chapter7/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-TOOLNAME = Kaleidoscope-Ch8
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := core mcjit native
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp
index 289209b3df49e..f880bb8ea0f0e 100644
--- a/examples/Kaleidoscope/Chapter8/toy.cpp
+++ b/examples/Kaleidoscope/Chapter8/toy.cpp
@@ -1,23 +1,31 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include <cctype>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
-using namespace llvm::orc;
+using namespace llvm::sys;
//===----------------------------------------------------------------------===//
// Lexer
@@ -51,70 +59,6 @@ enum Token {
tok_var = -13
};
-std::string getTokName(int Tok) {
- switch (Tok) {
- case tok_eof:
- return "eof";
- case tok_def:
- return "def";
- case tok_extern:
- return "extern";
- case tok_identifier:
- return "identifier";
- case tok_number:
- return "number";
- case tok_if:
- return "if";
- case tok_then:
- return "then";
- case tok_else:
- return "else";
- case tok_for:
- return "for";
- case tok_in:
- return "in";
- case tok_binary:
- return "binary";
- case tok_unary:
- return "unary";
- case tok_var:
- return "var";
- }
- return std::string(1, (char)Tok);
-}
-
-namespace {
-class PrototypeAST;
-class ExprAST;
-}
-static IRBuilder<> Builder(getGlobalContext());
-struct DebugInfo {
- DICompileUnit *TheCU;
- DIType *DblTy;
- std::vector<DIScope *> LexicalBlocks;
-
- void emitLocation(ExprAST *AST);
- DIType *getDoubleTy();
-} KSDbgInfo;
-
-struct SourceLocation {
- int Line;
- int Col;
-};
-static SourceLocation CurLoc;
-static SourceLocation LexLoc = {1, 0};
-
-static int advance() {
- int LastChar = getchar();
-
- if (LastChar == '\n' || LastChar == '\r') {
- LexLoc.Line++;
- LexLoc.Col = 0;
- } else
- LexLoc.Col++;
- return LastChar;
-}
-
static std::string IdentifierStr; // Filled in if tok_identifier
static double NumVal; // Filled in if tok_number
@@ -124,13 +68,11 @@ static int gettok() {
// Skip any whitespace.
while (isspace(LastChar))
- LastChar = advance();
-
- CurLoc = LexLoc;
+ LastChar = getchar();
if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
IdentifierStr = LastChar;
- while (isalnum((LastChar = advance())))
+ while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
if (IdentifierStr == "def")
@@ -160,7 +102,7 @@ static int gettok() {
std::string NumStr;
do {
NumStr += LastChar;
- LastChar = advance();
+ LastChar = getchar();
} while (isdigit(LastChar) || LastChar == '.');
NumVal = strtod(NumStr.c_str(), nullptr);
@@ -170,7 +112,7 @@ static int gettok() {
if (LastChar == '#') {
// Comment until end of line.
do
- LastChar = advance();
+ LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
@@ -183,7 +125,7 @@ static int gettok() {
// Otherwise, just return the character as its ascii value.
int ThisChar = LastChar;
- LastChar = advance();
+ LastChar = getchar();
return ThisChar;
}
@@ -191,24 +133,11 @@ static int gettok() {
// Abstract Syntax Tree (aka Parse Tree)
//===----------------------------------------------------------------------===//
namespace {
-
-raw_ostream &indent(raw_ostream &O, int size) {
- return O << std::string(size, ' ');
-}
-
/// ExprAST - Base class for all expression nodes.
class ExprAST {
- SourceLocation Loc;
-
public:
- ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
virtual ~ExprAST() {}
virtual Value *codegen() = 0;
- int getLine() const { return Loc.Line; }
- int getCol() const { return Loc.Col; }
- virtual raw_ostream &dump(raw_ostream &out, int ind) {
- return out << ':' << getLine() << ':' << getCol() << '\n';
- }
};
/// NumberExprAST - Expression class for numeric literals like "1.0".
@@ -217,9 +146,6 @@ class NumberExprAST : public ExprAST {
public:
NumberExprAST(double Val) : Val(Val) {}
- raw_ostream &dump(raw_ostream &out, int ind) override {
- return ExprAST::dump(out << Val, ind);
- }
Value *codegen() override;
};
@@ -228,13 +154,9 @@ class VariableExprAST : public ExprAST {
std::string Name;
public:
- VariableExprAST(SourceLocation Loc, const std::string &Name)
- : ExprAST(Loc), Name(Name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
const std::string &getName() const { return Name; }
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- return ExprAST::dump(out << Name, ind);
- }
};
/// UnaryExprAST - Expression class for a unary operator.
@@ -246,11 +168,6 @@ public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "unary" << Opcode, ind);
- Operand->dump(out, ind + 1);
- return out;
- }
};
/// BinaryExprAST - Expression class for a binary operator.
@@ -259,16 +176,10 @@ class BinaryExprAST : public ExprAST {
std::unique_ptr<ExprAST> LHS, RHS;
public:
- BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
- : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "binary" << Op, ind);
- LHS->dump(indent(out, ind) << "LHS:", ind + 1);
- RHS->dump(indent(out, ind) << "RHS:", ind + 1);
- return out;
- }
};
/// CallExprAST - Expression class for function calls.
@@ -277,16 +188,10 @@ class CallExprAST : public ExprAST {
std::vector<std::unique_ptr<ExprAST>> Args;
public:
- CallExprAST(SourceLocation Loc, const std::string &Callee,
+ CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
- : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {}
+ : Callee(Callee), Args(std::move(Args)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "call " << Callee, ind);
- for (const auto &Arg : Args)
- Arg->dump(indent(out, ind + 1), ind + 1);
- return out;
- }
};
/// IfExprAST - Expression class for if/then/else.
@@ -294,18 +199,10 @@ class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
- IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
- std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else)
- : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)),
- Else(std::move(Else)) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "if", ind);
- Cond->dump(indent(out, ind) << "Cond:", ind + 1);
- Then->dump(indent(out, ind) << "Then:", ind + 1);
- Else->dump(indent(out, ind) << "Else:", ind + 1);
- return out;
- }
};
/// ForExprAST - Expression class for for/in.
@@ -320,14 +217,6 @@ public:
: VarName(VarName), Start(std::move(Start)), End(std::move(End)),
Step(std::move(Step)), Body(std::move(Body)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "for", ind);
- Start->dump(indent(out, ind) << "Cond:", ind + 1);
- End->dump(indent(out, ind) << "End:", ind + 1);
- Step->dump(indent(out, ind) << "Step:", ind + 1);
- Body->dump(indent(out, ind) << "Body:", ind + 1);
- return out;
- }
};
/// VarExprAST - Expression class for var/in
@@ -341,13 +230,6 @@ public:
std::unique_ptr<ExprAST> Body)
: VarNames(std::move(VarNames)), Body(std::move(Body)) {}
Value *codegen() override;
- raw_ostream &dump(raw_ostream &out, int ind) override {
- ExprAST::dump(out << "var", ind);
- for (const auto &NamedVar : VarNames)
- NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1);
- Body->dump(indent(out, ind) << "Body:", ind + 1);
- return out;
- }
};
/// PrototypeAST - This class represents the "prototype" for a function,
@@ -358,14 +240,12 @@ class PrototypeAST {
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
- int Line;
public:
- PrototypeAST(SourceLocation Loc, const std::string &Name,
- std::vector<std::string> Args, bool IsOperator = false,
- unsigned Prec = 0)
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
: Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Prec), Line(Loc.Line) {}
+ Precedence(Prec) {}
Function *codegen();
const std::string &getName() const { return Name; }
@@ -378,7 +258,6 @@ public:
}
unsigned getBinaryPrecedence() const { return Precedence; }
- int getLine() const { return Line; }
};
/// FunctionAST - This class represents a function definition itself.
@@ -391,12 +270,6 @@ public:
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *codegen();
- raw_ostream &dump(raw_ostream &out, int ind) {
- indent(out, ind) << "FunctionAST\n";
- ++ind;
- indent(out, ind) << "Body:";
- return Body ? Body->dump(out, ind) : out << "null\n";
- }
};
} // end anonymous namespace
@@ -426,14 +299,14 @@ static int GetTokPrecedence() {
return TokPrec;
}
-/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -454,7 +327,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -465,18 +338,16 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
- SourceLocation LitLoc = CurLoc;
-
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(LitLoc, IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -486,7 +357,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -494,13 +365,11 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
- return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
- SourceLocation IfLoc = CurLoc;
-
getNextToken(); // eat the if.
// condition.
@@ -509,7 +378,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_then)
- return Error("expected then");
+ return LogError("expected then");
getNextToken(); // eat the then
auto Then = ParseExpression();
@@ -517,7 +386,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_else)
- return Error("expected else");
+ return LogError("expected else");
getNextToken();
@@ -525,7 +394,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
if (!Else)
return nullptr;
- return llvm::make_unique<IfExprAST>(IfLoc, std::move(Cond), std::move(Then),
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
@@ -534,20 +403,20 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
- return Error("expected identifier after for");
+ return LogError("expected identifier after for");
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '=')
- return Error("expected '=' after for");
+ return LogError("expected '=' after for");
getNextToken(); // eat '='.
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
- return Error("expected ',' after for start value");
+ return LogError("expected ',' after for start value");
getNextToken();
auto End = ParseExpression();
@@ -564,7 +433,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
}
if (CurTok != tok_in)
- return Error("expected 'in' after for");
+ return LogError("expected 'in' after for");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -584,9 +453,9 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
// At least one variable name is required.
if (CurTok != tok_identifier)
- return Error("expected identifier after var");
+ return LogError("expected identifier after var");
- while (1) {
+ while (true) {
std::string Name = IdentifierStr;
getNextToken(); // eat identifier.
@@ -608,12 +477,12 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the ','.
if (CurTok != tok_identifier)
- return Error("expected identifier list after var");
+ return LogError("expected identifier list after var");
}
// At this point, we have to have 'in'.
if (CurTok != tok_in)
- return Error("expected 'in' keyword after 'var'");
+ return LogError("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -633,7 +502,7 @@ static std::unique_ptr<ExprAST> ParseVarExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -670,7 +539,7 @@ static std::unique_ptr<ExprAST> ParseUnary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -680,7 +549,6 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
// Okay, we know this is a binop.
int BinOp = CurTok;
- SourceLocation BinLoc = CurLoc;
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
@@ -698,8 +566,8 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
}
// Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
@@ -721,14 +589,12 @@ static std::unique_ptr<ExprAST> ParseExpression() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
- SourceLocation FnLoc = CurLoc;
-
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
unsigned BinaryPrecedence = 30;
switch (CurTok) {
default:
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
case tok_identifier:
FnName = IdentifierStr;
Kind = 0;
@@ -737,7 +603,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_unary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected unary operator");
+ return LogErrorP("Expected unary operator");
FnName = "unary";
FnName += (char)CurTok;
Kind = 1;
@@ -746,7 +612,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_binary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected binary operator");
+ return LogErrorP("Expected binary operator");
FnName = "binary";
FnName += (char)CurTok;
Kind = 2;
@@ -755,7 +621,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return ErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedecnce: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -763,22 +629,22 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
}
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
// Verify right number of names for operator.
if (Kind && ArgNames.size() != Kind)
- return ErrorP("Invalid number of operands for operator");
+ return LogErrorP("Invalid number of operands for operator");
- return llvm::make_unique<PrototypeAST>(FnLoc, FnName, ArgNames, Kind != 0,
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
}
@@ -796,10 +662,9 @@ static std::unique_ptr<FunctionAST> ParseDefinition() {
/// toplevelexpr ::= expression
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- SourceLocation FnLoc = CurLoc;
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "__anon_expr",
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
@@ -813,55 +678,17 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
}
//===----------------------------------------------------------------------===//
-// Debug Info Support
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<DIBuilder> DBuilder;
-
-DIType *DebugInfo::getDoubleTy() {
- if (DblTy)
- return DblTy;
-
- DblTy = DBuilder->createBasicType("double", 64, 64, dwarf::DW_ATE_float);
- return DblTy;
-}
-
-void DebugInfo::emitLocation(ExprAST *AST) {
- if (!AST)
- return Builder.SetCurrentDebugLocation(DebugLoc());
- DIScope *Scope;
- if (LexicalBlocks.empty())
- Scope = TheCU;
- else
- Scope = LexicalBlocks.back();
- Builder.SetCurrentDebugLocation(
- DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
-}
-
-static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) {
- SmallVector<Metadata *, 8> EltTys;
- DIType *DblTy = KSDbgInfo.getDoubleTy();
-
- // Add the result type.
- EltTys.push_back(DblTy);
-
- for (unsigned i = 0, e = NumArgs; i != e; ++i)
- EltTys.push_back(DblTy);
-
- return DBuilder->createSubroutineType(DBuilder->getOrCreateTypeArray(EltTys));
-}
-
-//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
static std::map<std::string, AllocaInst *> NamedValues;
-static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
-Value *ErrorV(const char *Str) {
- Error(Str);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -886,22 +713,19 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
}
Value *NumberExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
- KSDbgInfo.emitLocation(this);
// Load the value.
return Builder.CreateLoad(V, Name.c_str());
}
@@ -913,15 +737,12 @@ Value *UnaryExprAST::codegen() {
Function *F = getFunction(std::string("unary") + Opcode);
if (!F)
- return ErrorV("Unknown unary operator");
+ return LogErrorV("Unknown unary operator");
- KSDbgInfo.emitLocation(this);
return Builder.CreateCall(F, OperandV, "unop");
}
Value *BinaryExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
@@ -930,7 +751,7 @@ Value *BinaryExprAST::codegen() {
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
if (!LHSE)
- return ErrorV("destination of '=' must be a variable");
+ return LogErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->codegen();
if (!Val)
@@ -939,7 +760,7 @@ Value *BinaryExprAST::codegen() {
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
if (!Variable)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
return Val;
@@ -960,8 +781,7 @@ Value *BinaryExprAST::codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
break;
}
@@ -976,16 +796,14 @@ Value *BinaryExprAST::codegen() {
}
Value *CallExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -998,24 +816,21 @@ Value *CallExprAST::codegen() {
}
Value *IfExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
Value *CondV = Cond->codegen();
if (!CondV)
return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
- CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB =
- BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -1045,8 +860,7 @@ Value *IfExprAST::codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN =
- Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -1078,8 +892,6 @@ Value *ForExprAST::codegen() {
// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- KSDbgInfo.emitLocation(this);
-
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->codegen();
if (!StartVal)
@@ -1090,8 +902,7 @@ Value *ForExprAST::codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB =
- BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -1118,7 +929,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -1134,11 +945,11 @@ Value *ForExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
- EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
- BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -1153,7 +964,7 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::codegen() {
@@ -1177,7 +988,7 @@ Value *VarExprAST::codegen() {
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1191,8 +1002,6 @@ Value *VarExprAST::codegen() {
NamedValues[VarName] = Alloca;
}
- KSDbgInfo.emitLocation(this);
-
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->codegen();
if (!BodyVal)
@@ -1208,10 +1017,9 @@ Value *VarExprAST::codegen() {
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -1238,46 +1046,15 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
- // Create a subprogram DIE for this function.
- DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
- KSDbgInfo.TheCU->getDirectory());
- DIScope *FContext = Unit;
- unsigned LineNo = P.getLine();
- unsigned ScopeLine = LineNo;
- DISubprogram *SP = DBuilder->createFunction(
- FContext, P.getName(), StringRef(), Unit, LineNo,
- CreateFunctionType(TheFunction->arg_size(), Unit),
- false /* internal linkage */, true /* definition */, ScopeLine,
- DINode::FlagPrototyped, false);
- TheFunction->setSubprogram(SP);
-
- // Push the current scope.
- KSDbgInfo.LexicalBlocks.push_back(SP);
-
- // Unset the location for the prologue emission (leading instructions with no
- // location in a function are considered part of the prologue and the debugger
- // will run past them when breaking on a function)
- KSDbgInfo.emitLocation(nullptr);
-
// Record the function arguments in the NamedValues map.
NamedValues.clear();
- unsigned ArgIdx = 0;
for (auto &Arg : TheFunction->args()) {
// Create an alloca for this variable.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
- // Create a debug descriptor for the variable.
- DILocalVariable *D = DBuilder->createParameterVariable(
- SP, Arg.getName(), ++ArgIdx, Unit, LineNo, KSDbgInfo.getDoubleTy(),
- true);
-
- DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
- DebugLoc::get(LineNo, 0, SP),
- Builder.GetInsertBlock());
-
// Store the initial value into the alloca.
Builder.CreateStore(&Arg, Alloca);
@@ -1285,15 +1062,10 @@ Function *FunctionAST::codegen() {
NamedValues[Arg.getName()] = Alloca;
}
- KSDbgInfo.emitLocation(Body.get());
-
if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
- // Pop off the lexical block for the function.
- KSDbgInfo.LexicalBlocks.pop_back();
-
// Validate the generated code, checking for consistency.
verifyFunction(*TheFunction);
@@ -1305,11 +1077,6 @@ Function *FunctionAST::codegen() {
if (P.isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
-
- // Pop off the lexical block for the function since we added it
- // unconditionally.
- KSDbgInfo.LexicalBlocks.pop_back();
-
return nullptr;
}
@@ -1317,16 +1084,17 @@ Function *FunctionAST::codegen() {
// Top-Level parsing and JIT Driver
//===----------------------------------------------------------------------===//
-static void InitializeModule() {
+static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
- TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
}
static void HandleDefinition() {
if (auto FnAST = ParseDefinition()) {
- if (!FnAST->codegen())
- fprintf(stderr, "Error reading function definition:");
+ if (auto *FnIR = FnAST->codegen()) {
+ fprintf(stderr, "Read function definition:");
+ FnIR->dump();
+ }
} else {
// Skip token for error recovery.
getNextToken();
@@ -1335,10 +1103,11 @@ static void HandleDefinition() {
static void HandleExtern() {
if (auto ProtoAST = ParseExtern()) {
- if (!ProtoAST->codegen())
- fprintf(stderr, "Error reading extern");
- else
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
} else {
// Skip token for error recovery.
getNextToken();
@@ -1348,9 +1117,7 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
- if (!FnAST->codegen()) {
- fprintf(stderr, "Error generating code for top level expr");
- }
+ FnAST->codegen();
} else {
// Skip token for error recovery.
getNextToken();
@@ -1359,7 +1126,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
switch (CurTok) {
case tok_eof:
return;
@@ -1400,50 +1167,74 @@ extern "C" double printd(double X) {
//===----------------------------------------------------------------------===//
int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
// Install standard binary operators.
// 1 is lowest precedence.
- BinopPrecedence['='] = 2;
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
BinopPrecedence['*'] = 40; // highest.
// Prime the first token.
+ fprintf(stderr, "ready> ");
getNextToken();
- TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+ InitializeModuleAndPassManager();
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
- InitializeModule();
+ // Initialize the target registry etc.
+ InitializeAllTargetInfos();
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmParsers();
+ InitializeAllAsmPrinters();
+
+ auto TargetTriple = sys::getDefaultTargetTriple();
+ TheModule->setTargetTriple(TargetTriple);
+
+ std::string Error;
+ auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
+
+ // Print an error and exit if we couldn't find the requested target.
+ // This generally occurs if we've forgotten to initialise the
+ // TargetRegistry or we have a bogus target triple.
+ if (!Target) {
+ errs() << Error;
+ return 1;
+ }
- // Add the current debug info version into the module.
- TheModule->addModuleFlag(Module::Warning, "Debug Info Version",
- DEBUG_METADATA_VERSION);
+ auto CPU = "generic";
+ auto Features = "";
- // Darwin only supports dwarf2.
- if (Triple(sys::getProcessTriple()).isOSDarwin())
- TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2);
+ TargetOptions opt;
+ auto RM = Optional<Reloc::Model>();
+ auto TheTargetMachine =
+ Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
- // Construct the DIBuilder, we do this here because we need the module.
- DBuilder = llvm::make_unique<DIBuilder>(*TheModule);
+ TheModule->setDataLayout(TheTargetMachine->createDataLayout());
- // Create the compile unit for the module.
- // Currently down as "fib.ks" as a filename since we're redirecting stdin
- // but we'd like actual source locations.
- KSDbgInfo.TheCU = DBuilder->createCompileUnit(
- dwarf::DW_LANG_C, "fib.ks", ".", "Kaleidoscope Compiler", 0, "", 0);
+ auto Filename = "output.o";
+ std::error_code EC;
+ raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
- // Run the main "interpreter loop" now.
- MainLoop();
+ if (EC) {
+ errs() << "Could not open file: " << EC.message();
+ return 1;
+ }
+
+ legacy::PassManager pass;
+ auto FileType = TargetMachine::CGFT_ObjectFile;
+
+ if (TheTargetMachine->addPassesToEmitFile(pass, dest, FileType)) {
+ errs() << "TheTargetMachine can't emit a file of this type";
+ return 1;
+ }
- // Finalize the debug info.
- DBuilder->finalize();
+ pass.run(*TheModule);
+ dest.flush();
- // Print out all of the generated code.
- TheModule->dump();
+ outs() << "Wrote " << Filename << "\n";
return 0;
}
diff --git a/examples/Kaleidoscope/Orc/initial/CMakeLists.txt b/examples/Kaleidoscope/Chapter9/CMakeLists.txt
index 4f21e1c622186..a85b2c5e8b318 100644
--- a/examples/Kaleidoscope/Orc/initial/CMakeLists.txt
+++ b/examples/Kaleidoscope/Chapter9/CMakeLists.txt
@@ -2,11 +2,12 @@ set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
Object
- RuntimeDyld
Support
native
)
-add_kaleidoscope_chapter(Kaleidoscope-Orc-initial
+add_kaleidoscope_chapter(Kaleidoscope-Ch9
toy.cpp
)
+
+export_executable_symbols(Kaleidoscope-Ch9)
diff --git a/examples/Kaleidoscope/Chapter9/toy.cpp b/examples/Kaleidoscope/Chapter9/toy.cpp
new file mode 100644
index 0000000000000..a482ccd735256
--- /dev/null
+++ b/examples/Kaleidoscope/Chapter9/toy.cpp
@@ -0,0 +1,1445 @@
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Transforms/Scalar.h"
+#include <cctype>
+#include <cstdio>
+#include <map>
+#include <string>
+#include <vector>
+#include "../include/KaleidoscopeJIT.h"
+
+using namespace llvm;
+using namespace llvm::orc;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+ tok_eof = -1,
+
+ // commands
+ tok_def = -2,
+ tok_extern = -3,
+
+ // primary
+ tok_identifier = -4,
+ tok_number = -5,
+
+ // control
+ tok_if = -6,
+ tok_then = -7,
+ tok_else = -8,
+ tok_for = -9,
+ tok_in = -10,
+
+ // operators
+ tok_binary = -11,
+ tok_unary = -12,
+
+ // var definition
+ tok_var = -13
+};
+
+std::string getTokName(int Tok) {
+ switch (Tok) {
+ case tok_eof:
+ return "eof";
+ case tok_def:
+ return "def";
+ case tok_extern:
+ return "extern";
+ case tok_identifier:
+ return "identifier";
+ case tok_number:
+ return "number";
+ case tok_if:
+ return "if";
+ case tok_then:
+ return "then";
+ case tok_else:
+ return "else";
+ case tok_for:
+ return "for";
+ case tok_in:
+ return "in";
+ case tok_binary:
+ return "binary";
+ case tok_unary:
+ return "unary";
+ case tok_var:
+ return "var";
+ }
+ return std::string(1, (char)Tok);
+}
+
+namespace {
+class PrototypeAST;
+class ExprAST;
+}
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
+struct DebugInfo {
+ DICompileUnit *TheCU;
+ DIType *DblTy;
+ std::vector<DIScope *> LexicalBlocks;
+
+ void emitLocation(ExprAST *AST);
+ DIType *getDoubleTy();
+} KSDbgInfo;
+
+struct SourceLocation {
+ int Line;
+ int Col;
+};
+static SourceLocation CurLoc;
+static SourceLocation LexLoc = {1, 0};
+
+static int advance() {
+ int LastChar = getchar();
+
+ if (LastChar == '\n' || LastChar == '\r') {
+ LexLoc.Line++;
+ LexLoc.Col = 0;
+ } else
+ LexLoc.Col++;
+ return LastChar;
+}
+
+static std::string IdentifierStr; // Filled in if tok_identifier
+static double NumVal; // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+ static int LastChar = ' ';
+
+ // Skip any whitespace.
+ while (isspace(LastChar))
+ LastChar = advance();
+
+ CurLoc = LexLoc;
+
+ if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+ IdentifierStr = LastChar;
+ while (isalnum((LastChar = advance())))
+ IdentifierStr += LastChar;
+
+ if (IdentifierStr == "def")
+ return tok_def;
+ if (IdentifierStr == "extern")
+ return tok_extern;
+ if (IdentifierStr == "if")
+ return tok_if;
+ if (IdentifierStr == "then")
+ return tok_then;
+ if (IdentifierStr == "else")
+ return tok_else;
+ if (IdentifierStr == "for")
+ return tok_for;
+ if (IdentifierStr == "in")
+ return tok_in;
+ if (IdentifierStr == "binary")
+ return tok_binary;
+ if (IdentifierStr == "unary")
+ return tok_unary;
+ if (IdentifierStr == "var")
+ return tok_var;
+ return tok_identifier;
+ }
+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ std::string NumStr;
+ do {
+ NumStr += LastChar;
+ LastChar = advance();
+ } while (isdigit(LastChar) || LastChar == '.');
+
+ NumVal = strtod(NumStr.c_str(), nullptr);
+ return tok_number;
+ }
+
+ if (LastChar == '#') {
+ // Comment until end of line.
+ do
+ LastChar = advance();
+ while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
+
+ if (LastChar != EOF)
+ return gettok();
+ }
+
+ // Check for end of file. Don't eat the EOF.
+ if (LastChar == EOF)
+ return tok_eof;
+
+ // Otherwise, just return the character as its ascii value.
+ int ThisChar = LastChar;
+ LastChar = advance();
+ return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+namespace {
+
+raw_ostream &indent(raw_ostream &O, int size) {
+ return O << std::string(size, ' ');
+}
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+ SourceLocation Loc;
+
+public:
+ ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
+ virtual ~ExprAST() {}
+ virtual Value *codegen() = 0;
+ int getLine() const { return Loc.Line; }
+ int getCol() const { return Loc.Col; }
+ virtual raw_ostream &dump(raw_ostream &out, int ind) {
+ return out << ':' << getLine() << ':' << getCol() << '\n';
+ }
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+ double Val;
+
+public:
+ NumberExprAST(double Val) : Val(Val) {}
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ return ExprAST::dump(out << Val, ind);
+ }
+ Value *codegen() override;
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+ std::string Name;
+
+public:
+ VariableExprAST(SourceLocation Loc, const std::string &Name)
+ : ExprAST(Loc), Name(Name) {}
+ const std::string &getName() const { return Name; }
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ return ExprAST::dump(out << Name, ind);
+ }
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+ char Opcode;
+ std::unique_ptr<ExprAST> Operand;
+
+public:
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "unary" << Opcode, ind);
+ Operand->dump(out, ind + 1);
+ return out;
+ }
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
+public:
+ BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "binary" << Op, ind);
+ LHS->dump(indent(out, ind) << "LHS:", ind + 1);
+ RHS->dump(indent(out, ind) << "RHS:", ind + 1);
+ return out;
+ }
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+ std::string Callee;
+ std::vector<std::unique_ptr<ExprAST>> Args;
+
+public:
+ CallExprAST(SourceLocation Loc, const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "call " << Callee, ind);
+ for (const auto &Arg : Args)
+ Arg->dump(indent(out, ind + 1), ind + 1);
+ return out;
+ }
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+ std::unique_ptr<ExprAST> Cond, Then, Else;
+
+public:
+ IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
+ std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else)
+ : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)),
+ Else(std::move(Else)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "if", ind);
+ Cond->dump(indent(out, ind) << "Cond:", ind + 1);
+ Then->dump(indent(out, ind) << "Then:", ind + 1);
+ Else->dump(indent(out, ind) << "Else:", ind + 1);
+ return out;
+ }
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+ std::string VarName;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
+
+public:
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "for", ind);
+ Start->dump(indent(out, ind) << "Cond:", ind + 1);
+ End->dump(indent(out, ind) << "End:", ind + 1);
+ Step->dump(indent(out, ind) << "Step:", ind + 1);
+ Body->dump(indent(out, ind) << "Body:", ind + 1);
+ return out;
+ }
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ Value *codegen() override;
+ raw_ostream &dump(raw_ostream &out, int ind) override {
+ ExprAST::dump(out << "var", ind);
+ for (const auto &NamedVar : VarNames)
+ NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1);
+ Body->dump(indent(out, ind) << "Body:", ind + 1);
+ return out;
+ }
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
+class PrototypeAST {
+ std::string Name;
+ std::vector<std::string> Args;
+ bool IsOperator;
+ unsigned Precedence; // Precedence if a binary op.
+ int Line;
+
+public:
+ PrototypeAST(SourceLocation Loc, const std::string &Name,
+ std::vector<std::string> Args, bool IsOperator = false,
+ unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec), Line(Loc.Line) {}
+ Function *codegen();
+ const std::string &getName() const { return Name; }
+
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
+
+ char getOperatorName() const {
+ assert(isUnaryOp() || isBinaryOp());
+ return Name[Name.size() - 1];
+ }
+
+ unsigned getBinaryPrecedence() const { return Precedence; }
+ int getLine() const { return Line; }
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
+public:
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ Function *codegen();
+ raw_ostream &dump(raw_ostream &out, int ind) {
+ indent(out, ind) << "FunctionAST\n";
+ ++ind;
+ indent(out, ind) << "Body:";
+ return Body ? Body->dump(out, ind) : out << "null\n";
+ }
+};
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
+/// token the parser is looking at. getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() { return CurTok = gettok(); }
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+ if (!isascii(CurTok))
+ return -1;
+
+ // Make sure it's a declared binop.
+ int TokPrec = BinopPrecedence[CurTok];
+ if (TokPrec <= 0)
+ return -1;
+ return TokPrec;
+}
+
+/// LogError* - These are little helper functions for error handling.
+std::unique_ptr<ExprAST> LogError(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+static std::unique_ptr<ExprAST> ParseExpression();
+
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return LogError("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
+/// identifierexpr
+/// ::= identifier
+/// ::= identifier '(' expression* ')'
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+ std::string IdName = IdentifierStr;
+
+ SourceLocation LitLoc = CurLoc;
+
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '(') // Simple variable ref.
+ return llvm::make_unique<VariableExprAST>(LitLoc, IdName);
+
+ // Call.
+ getNextToken(); // eat (
+ std::vector<std::unique_ptr<ExprAST>> Args;
+ if (CurTok != ')') {
+ while (1) {
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
+
+ if (CurTok == ')')
+ break;
+
+ if (CurTok != ',')
+ return LogError("Expected ')' or ',' in argument list");
+ getNextToken();
+ }
+ }
+
+ // Eat the ')'.
+ getNextToken();
+
+ return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static std::unique_ptr<ExprAST> ParseIfExpr() {
+ SourceLocation IfLoc = CurLoc;
+
+ getNextToken(); // eat the if.
+
+ // condition.
+ auto Cond = ParseExpression();
+ if (!Cond)
+ return nullptr;
+
+ if (CurTok != tok_then)
+ return LogError("expected then");
+ getNextToken(); // eat the then
+
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
+
+ if (CurTok != tok_else)
+ return LogError("expected else");
+
+ getNextToken();
+
+ auto Else = ParseExpression();
+ if (!Else)
+ return nullptr;
+
+ return llvm::make_unique<IfExprAST>(IfLoc, std::move(Cond), std::move(Then),
+ std::move(Else));
+}
+
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+static std::unique_ptr<ExprAST> ParseForExpr() {
+ getNextToken(); // eat the for.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after for");
+
+ std::string IdName = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ if (CurTok != '=')
+ return LogError("expected '=' after for");
+ getNextToken(); // eat '='.
+
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
+ if (CurTok != ',')
+ return LogError("expected ',' after for start value");
+ getNextToken();
+
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
+
+ // The step value is optional.
+ std::unique_ptr<ExprAST> Step;
+ if (CurTok == ',') {
+ getNextToken();
+ Step = ParseExpression();
+ if (!Step)
+ return nullptr;
+ }
+
+ if (CurTok != tok_in)
+ return LogError("expected 'in' after for");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
+}
+
+/// varexpr ::= 'var' identifier ('=' expression)?
+// (',' identifier ('=' expression)?)* 'in' expression
+static std::unique_ptr<ExprAST> ParseVarExpr() {
+ getNextToken(); // eat the var.
+
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+
+ // At least one variable name is required.
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier after var");
+
+ while (1) {
+ std::string Name = IdentifierStr;
+ getNextToken(); // eat identifier.
+
+ // Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
+ if (CurTok == '=') {
+ getNextToken(); // eat the '='.
+
+ Init = ParseExpression();
+ if (!Init)
+ return nullptr;
+ }
+
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
+
+ // End of var list, exit loop.
+ if (CurTok != ',')
+ break;
+ getNextToken(); // eat the ','.
+
+ if (CurTok != tok_identifier)
+ return LogError("expected identifier list after var");
+ }
+
+ // At this point, we have to have 'in'.
+ if (CurTok != tok_in)
+ return LogError("expected 'in' keyword after 'var'");
+ getNextToken(); // eat 'in'.
+
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
+
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
+}
+
+/// primary
+/// ::= identifierexpr
+/// ::= numberexpr
+/// ::= parenexpr
+/// ::= ifexpr
+/// ::= forexpr
+/// ::= varexpr
+static std::unique_ptr<ExprAST> ParsePrimary() {
+ switch (CurTok) {
+ default:
+ return LogError("unknown token when expecting an expression");
+ case tok_identifier:
+ return ParseIdentifierExpr();
+ case tok_number:
+ return ParseNumberExpr();
+ case '(':
+ return ParseParenExpr();
+ case tok_if:
+ return ParseIfExpr();
+ case tok_for:
+ return ParseForExpr();
+ case tok_var:
+ return ParseVarExpr();
+ }
+}
+
+/// unary
+/// ::= primary
+/// ::= '!' unary
+static std::unique_ptr<ExprAST> ParseUnary() {
+ // If the current token is not an operator, it must be a primary expr.
+ if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+ return ParsePrimary();
+
+ // If this is a unary operator, read it.
+ int Opc = CurTok;
+ getNextToken();
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
+}
+
+/// binoprhs
+/// ::= ('+' unary)*
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
+ // If this is a binop, find its precedence.
+ while (1) {
+ int TokPrec = GetTokPrecedence();
+
+ // If this is a binop that binds at least as tightly as the current binop,
+ // consume it, otherwise we are done.
+ if (TokPrec < ExprPrec)
+ return LHS;
+
+ // Okay, we know this is a binop.
+ int BinOp = CurTok;
+ SourceLocation BinLoc = CurLoc;
+ getNextToken(); // eat binop
+
+ // Parse the unary expression after the binary operator.
+ auto RHS = ParseUnary();
+ if (!RHS)
+ return nullptr;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ int NextPrec = GetTokPrecedence();
+ if (TokPrec < NextPrec) {
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
+ }
+
+ // Merge LHS/RHS.
+ LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
+ std::move(RHS));
+ }
+}
+
+/// expression
+/// ::= unary binoprhs
+///
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS)
+ return nullptr;
+
+ return ParseBinOpRHS(0, std::move(LHS));
+}
+
+/// prototype
+/// ::= id '(' id* ')'
+/// ::= binary LETTER number? (id, id)
+/// ::= unary LETTER (id)
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
+ std::string FnName;
+
+ SourceLocation FnLoc = CurLoc;
+
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned BinaryPrecedence = 30;
+
+ switch (CurTok) {
+ default:
+ return LogErrorP("Expected function name in prototype");
+ case tok_identifier:
+ FnName = IdentifierStr;
+ Kind = 0;
+ getNextToken();
+ break;
+ case tok_unary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected unary operator");
+ FnName = "unary";
+ FnName += (char)CurTok;
+ Kind = 1;
+ getNextToken();
+ break;
+ case tok_binary:
+ getNextToken();
+ if (!isascii(CurTok))
+ return LogErrorP("Expected binary operator");
+ FnName = "binary";
+ FnName += (char)CurTok;
+ Kind = 2;
+ getNextToken();
+
+ // Read the precedence if present.
+ if (CurTok == tok_number) {
+ if (NumVal < 1 || NumVal > 100)
+ return LogErrorP("Invalid precedecnce: must be 1..100");
+ BinaryPrecedence = (unsigned)NumVal;
+ getNextToken();
+ }
+ break;
+ }
+
+ if (CurTok != '(')
+ return LogErrorP("Expected '(' in prototype");
+
+ std::vector<std::string> ArgNames;
+ while (getNextToken() == tok_identifier)
+ ArgNames.push_back(IdentifierStr);
+ if (CurTok != ')')
+ return LogErrorP("Expected ')' in prototype");
+
+ // success.
+ getNextToken(); // eat ')'.
+
+ // Verify right number of names for operator.
+ if (Kind && ArgNames.size() != Kind)
+ return LogErrorP("Invalid number of operands for operator");
+
+ return llvm::make_unique<PrototypeAST>(FnLoc, FnName, ArgNames, Kind != 0,
+ BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static std::unique_ptr<FunctionAST> ParseDefinition() {
+ getNextToken(); // eat def.
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
+
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
+}
+
+/// toplevelexpr ::= expression
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ SourceLocation FnLoc = CurLoc;
+ if (auto E = ParseExpression()) {
+ // Make an anonymous proto.
+ auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "__anon_expr",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ }
+ return nullptr;
+}
+
+/// external ::= 'extern' prototype
+static std::unique_ptr<PrototypeAST> ParseExtern() {
+ getNextToken(); // eat extern.
+ return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Debug Info Support
+//===----------------------------------------------------------------------===//
+
+static std::unique_ptr<DIBuilder> DBuilder;
+
+DIType *DebugInfo::getDoubleTy() {
+ if (DblTy)
+ return DblTy;
+
+ DblTy = DBuilder->createBasicType("double", 64, 64, dwarf::DW_ATE_float);
+ return DblTy;
+}
+
+void DebugInfo::emitLocation(ExprAST *AST) {
+ if (!AST)
+ return Builder.SetCurrentDebugLocation(DebugLoc());
+ DIScope *Scope;
+ if (LexicalBlocks.empty())
+ Scope = TheCU;
+ else
+ Scope = LexicalBlocks.back();
+ Builder.SetCurrentDebugLocation(
+ DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
+}
+
+static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) {
+ SmallVector<Metadata *, 8> EltTys;
+ DIType *DblTy = KSDbgInfo.getDoubleTy();
+
+ // Add the result type.
+ EltTys.push_back(DblTy);
+
+ for (unsigned i = 0, e = NumArgs; i != e; ++i)
+ EltTys.push_back(DblTy);
+
+ return DBuilder->createSubroutineType(DBuilder->getOrCreateTypeArray(EltTys));
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static std::unique_ptr<Module> TheModule;
+static std::map<std::string, AllocaInst *> NamedValues;
+static std::unique_ptr<KaleidoscopeJIT> TheJIT;
+static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
+
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
+ return nullptr;
+}
+
+Function *getFunction(std::string Name) {
+ // First, see if the function has already been added to the current module.
+ if (auto *F = TheModule->getFunction(Name))
+ return F;
+
+ // If not, check whether we can codegen the declaration from some existing
+ // prototype.
+ auto FI = FunctionProtos.find(Name);
+ if (FI != FunctionProtos.end())
+ return FI->second->codegen();
+
+ // If no existing prototype exists, return null.
+ return nullptr;
+}
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function. This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+ const std::string &VarName) {
+ IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
+ TheFunction->getEntryBlock().begin());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr,
+ VarName.c_str());
+}
+
+Value *NumberExprAST::codegen() {
+ KSDbgInfo.emitLocation(this);
+ return ConstantFP::get(TheContext, APFloat(Val));
+}
+
+Value *VariableExprAST::codegen() {
+ // Look this variable up in the function.
+ Value *V = NamedValues[Name];
+ if (!V)
+ return LogErrorV("Unknown variable name");
+
+ KSDbgInfo.emitLocation(this);
+ // Load the value.
+ return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
+ if (!OperandV)
+ return nullptr;
+
+ Function *F = getFunction(std::string("unary") + Opcode);
+ if (!F)
+ return LogErrorV("Unknown unary operator");
+
+ KSDbgInfo.emitLocation(this);
+ return Builder.CreateCall(F, OperandV, "unop");
+}
+
+Value *BinaryExprAST::codegen() {
+ KSDbgInfo.emitLocation(this);
+
+ // Special case '=' because we don't want to emit the LHS as an expression.
+ if (Op == '=') {
+ // Assignment requires the LHS to be an identifier.
+ // This assume we're building without RTTI because LLVM builds that way by
+ // default. If you build LLVM with RTTI this can be changed to a
+ // dynamic_cast for automatic error checking.
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
+ if (!LHSE)
+ return LogErrorV("destination of '=' must be a variable");
+ // Codegen the RHS.
+ Value *Val = RHS->codegen();
+ if (!Val)
+ return nullptr;
+
+ // Look up the name.
+ Value *Variable = NamedValues[LHSE->getName()];
+ if (!Variable)
+ return LogErrorV("Unknown variable name");
+
+ Builder.CreateStore(Val, Variable);
+ return Val;
+ }
+
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
+ if (!L || !R)
+ return nullptr;
+
+ switch (Op) {
+ case '+':
+ return Builder.CreateFAdd(L, R, "addtmp");
+ case '-':
+ return Builder.CreateFSub(L, R, "subtmp");
+ case '*':
+ return Builder.CreateFMul(L, R, "multmp");
+ case '<':
+ L = Builder.CreateFCmpULT(L, R, "cmptmp");
+ // Convert bool 0/1 to double 0.0 or 1.0
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ default:
+ break;
+ }
+
+ // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+ // a call to it.
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary operator not found!");
+
+ Value *Ops[] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
+}
+
+Value *CallExprAST::codegen() {
+ KSDbgInfo.emitLocation(this);
+
+ // Look up the name in the global module table.
+ Function *CalleeF = getFunction(Callee);
+ if (!CalleeF)
+ return LogErrorV("Unknown function referenced");
+
+ // If argument mismatch error.
+ if (CalleeF->arg_size() != Args.size())
+ return LogErrorV("Incorrect # arguments passed");
+
+ std::vector<Value *> ArgsV;
+ for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+ ArgsV.push_back(Args[i]->codegen());
+ if (!ArgsV.back())
+ return nullptr;
+ }
+
+ return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
+}
+
+Value *IfExprAST::codegen() {
+ KSDbgInfo.emitLocation(this);
+
+ Value *CondV = Cond->codegen();
+ if (!CondV)
+ return nullptr;
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create blocks for the then and else cases. Insert the 'then' block at the
+ // end of the function.
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
+ Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+
+ // Emit then value.
+ Builder.SetInsertPoint(ThenBB);
+
+ Value *ThenV = Then->codegen();
+ if (!ThenV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+ ThenBB = Builder.GetInsertBlock();
+
+ // Emit else block.
+ TheFunction->getBasicBlockList().push_back(ElseBB);
+ Builder.SetInsertPoint(ElseBB);
+
+ Value *ElseV = Else->codegen();
+ if (!ElseV)
+ return nullptr;
+
+ Builder.CreateBr(MergeBB);
+ // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+ ElseBB = Builder.GetInsertBlock();
+
+ // Emit merge block.
+ TheFunction->getBasicBlockList().push_back(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
+ PN->addIncoming(ThenV, ThenBB);
+ PN->addIncoming(ElseV, ElseBB);
+ return PN;
+}
+
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
+Value *ForExprAST::codegen() {
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Create an alloca for the variable in the entry block.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+
+ KSDbgInfo.emitLocation(this);
+
+ // Emit the start code first, without 'variable' in scope.
+ Value *StartVal = Start->codegen();
+ if (!StartVal)
+ return nullptr;
+
+ // Store the value into the alloca.
+ Builder.CreateStore(StartVal, Alloca);
+
+ // Make the new basic block for the loop header, inserting after current
+ // block.
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
+ // Insert an explicit fall through from the current block to the LoopBB.
+ Builder.CreateBr(LoopBB);
+
+ // Start insertion in LoopBB.
+ Builder.SetInsertPoint(LoopBB);
+
+ // Within the loop, the variable is defined equal to the PHI node. If it
+ // shadows an existing variable, we have to restore it, so save it now.
+ AllocaInst *OldVal = NamedValues[VarName];
+ NamedValues[VarName] = Alloca;
+
+ // Emit the body of the loop. This, like any other expr, can change the
+ // current BB. Note that we ignore the value computed by the body, but don't
+ // allow an error.
+ if (!Body->codegen())
+ return nullptr;
+
+ // Emit the step value.
+ Value *StepVal = nullptr;
+ if (Step) {
+ StepVal = Step->codegen();
+ if (!StepVal)
+ return nullptr;
+ } else {
+ // If not specified, use 1.0.
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // Compute the end condition.
+ Value *EndCond = End->codegen();
+ if (!EndCond)
+ return nullptr;
+
+ // Reload, increment, and restore the alloca. This handles the case where
+ // the body of the loop mutates the variable.
+ Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+ Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
+ Builder.CreateStore(NextVar, Alloca);
+
+ // Convert condition to a bool by comparing equal to 0.0.
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ // Create the "after loop" block and insert it.
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
+ // Insert the conditional branch into the end of LoopEndBB.
+ Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+
+ // Any new code will be inserted in AfterBB.
+ Builder.SetInsertPoint(AfterBB);
+
+ // Restore the unshadowed variable.
+ if (OldVal)
+ NamedValues[VarName] = OldVal;
+ else
+ NamedValues.erase(VarName);
+
+ // for expr always returns 0.0.
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}
+
+Value *VarExprAST::codegen() {
+ std::vector<AllocaInst *> OldBindings;
+
+ Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+ // Register all variables and emit their initializer.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+ const std::string &VarName = VarNames[i].first;
+ ExprAST *Init = VarNames[i].second.get();
+
+ // Emit the initializer before adding the variable to scope, this prevents
+ // the initializer from referencing the variable itself, and permits stuff
+ // like this:
+ // var a = 1 in
+ // var a = a in ... # refers to outer 'a'.
+ Value *InitVal;
+ if (Init) {
+ InitVal = Init->codegen();
+ if (!InitVal)
+ return nullptr;
+ } else { // If not specified, use 0.0.
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
+ }
+
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+ Builder.CreateStore(InitVal, Alloca);
+
+ // Remember the old variable binding so that we can restore the binding when
+ // we unrecurse.
+ OldBindings.push_back(NamedValues[VarName]);
+
+ // Remember this binding.
+ NamedValues[VarName] = Alloca;
+ }
+
+ KSDbgInfo.emitLocation(this);
+
+ // Codegen the body, now that all vars are in scope.
+ Value *BodyVal = Body->codegen();
+ if (!BodyVal)
+ return nullptr;
+
+ // Pop all our variables from scope.
+ for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+ NamedValues[VarNames[i].first] = OldBindings[i];
+
+ // Return the body computation.
+ return BodyVal;
+}
+
+Function *PrototypeAST::codegen() {
+ // Make the function type: double(double,double) etc.
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
+
+ Function *F =
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
+
+ // Set names for all arguments.
+ unsigned Idx = 0;
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
+
+ return F;
+}
+
+Function *FunctionAST::codegen() {
+ // Transfer ownership of the prototype to the FunctionProtos map, but keep a
+ // reference to it for use below.
+ auto &P = *Proto;
+ FunctionProtos[Proto->getName()] = std::move(Proto);
+ Function *TheFunction = getFunction(P.getName());
+ if (!TheFunction)
+ return nullptr;
+
+ // If this is an operator, install it.
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
+ // Create a new basic block to start insertion into.
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
+ Builder.SetInsertPoint(BB);
+
+ // Create a subprogram DIE for this function.
+ DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
+ KSDbgInfo.TheCU->getDirectory());
+ DIScope *FContext = Unit;
+ unsigned LineNo = P.getLine();
+ unsigned ScopeLine = LineNo;
+ DISubprogram *SP = DBuilder->createFunction(
+ FContext, P.getName(), StringRef(), Unit, LineNo,
+ CreateFunctionType(TheFunction->arg_size(), Unit),
+ false /* internal linkage */, true /* definition */, ScopeLine,
+ DINode::FlagPrototyped, false);
+ TheFunction->setSubprogram(SP);
+
+ // Push the current scope.
+ KSDbgInfo.LexicalBlocks.push_back(SP);
+
+ // Unset the location for the prologue emission (leading instructions with no
+ // location in a function are considered part of the prologue and the debugger
+ // will run past them when breaking on a function)
+ KSDbgInfo.emitLocation(nullptr);
+
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ unsigned ArgIdx = 0;
+ for (auto &Arg : TheFunction->args()) {
+ // Create an alloca for this variable.
+ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
+
+ // Create a debug descriptor for the variable.
+ DILocalVariable *D = DBuilder->createParameterVariable(
+ SP, Arg.getName(), ++ArgIdx, Unit, LineNo, KSDbgInfo.getDoubleTy(),
+ true);
+
+ DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
+ DebugLoc::get(LineNo, 0, SP),
+ Builder.GetInsertBlock());
+
+ // Store the initial value into the alloca.
+ Builder.CreateStore(&Arg, Alloca);
+
+ // Add arguments to variable symbol table.
+ NamedValues[Arg.getName()] = Alloca;
+ }
+
+ KSDbgInfo.emitLocation(Body.get());
+
+ if (Value *RetVal = Body->codegen()) {
+ // Finish off the function.
+ Builder.CreateRet(RetVal);
+
+ // Pop off the lexical block for the function.
+ KSDbgInfo.LexicalBlocks.pop_back();
+
+ // Validate the generated code, checking for consistency.
+ verifyFunction(*TheFunction);
+
+ return TheFunction;
+ }
+
+ // Error reading body, remove function.
+ TheFunction->eraseFromParent();
+
+ if (P.isBinaryOp())
+ BinopPrecedence.erase(Proto->getOperatorName());
+
+ // Pop off the lexical block for the function since we added it
+ // unconditionally.
+ KSDbgInfo.LexicalBlocks.pop_back();
+
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static void InitializeModule() {
+ // Open a new module.
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
+ TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
+}
+
+static void HandleDefinition() {
+ if (auto FnAST = ParseDefinition()) {
+ if (!FnAST->codegen())
+ fprintf(stderr, "Error reading function definition:");
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleExtern() {
+ if (auto ProtoAST = ParseExtern()) {
+ if (!ProtoAST->codegen())
+ fprintf(stderr, "Error reading extern");
+ else
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (!FnAST->codegen()) {
+ fprintf(stderr, "Error generating code for top level expr");
+ }
+ } else {
+ // Skip token for error recovery.
+ getNextToken();
+ }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+ while (1) {
+ switch (CurTok) {
+ case tok_eof:
+ return;
+ case ';': // ignore top-level semicolons.
+ getNextToken();
+ break;
+ case tok_def:
+ HandleDefinition();
+ break;
+ case tok_extern:
+ HandleExtern();
+ break;
+ default:
+ HandleTopLevelExpression();
+ break;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 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) {
+ fprintf(stderr, "%f\n", X);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
+
+ // Install standard binary operators.
+ // 1 is lowest precedence.
+ BinopPrecedence['='] = 2;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['+'] = 20;
+ BinopPrecedence['-'] = 20;
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+ getNextToken();
+
+ TheJIT = llvm::make_unique<KaleidoscopeJIT>();
+
+ InitializeModule();
+
+ // Add the current debug info version into the module.
+ TheModule->addModuleFlag(Module::Warning, "Debug Info Version",
+ DEBUG_METADATA_VERSION);
+
+ // Darwin only supports dwarf2.
+ if (Triple(sys::getProcessTriple()).isOSDarwin())
+ TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2);
+
+ // Construct the DIBuilder, we do this here because we need the module.
+ DBuilder = llvm::make_unique<DIBuilder>(*TheModule);
+
+ // Create the compile unit for the module.
+ // Currently down as "fib.ks" as a filename since we're redirecting stdin
+ // but we'd like actual source locations.
+ KSDbgInfo.TheCU = DBuilder->createCompileUnit(
+ dwarf::DW_LANG_C, "fib.ks", ".", "Kaleidoscope Compiler", 0, "", 0);
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ // Finalize the debug info.
+ DBuilder->finalize();
+
+ // Print out all of the generated code.
+ TheModule->dump();
+
+ return 0;
+}
diff --git a/examples/Kaleidoscope/MCJIT/cached/Makefile b/examples/Kaleidoscope/MCJIT/cached/Makefile
deleted file mode 100644
index dde39a75d7675..0000000000000
--- a/examples/Kaleidoscope/MCJIT/cached/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-all: toy-mcjit toy-jit toy-ir-gen
-
-toy-mcjit : toy.cpp
- clang++ toy.cpp -g -O3 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --libs core mcjit native irreader` -o toy-mcjit
-
-toy-jit : toy-jit.cpp
- clang++ toy-jit.cpp -g -O3 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --libs core jit native irreader` -o toy-jit
-
-# This is a special build for the purpose of converting Kaleidoscope input to an IR file
-toy-ir-gen : toy-jit.cpp
- clang++ toy-jit.cpp -g -O3 -rdynamic -fno-rtti -DDUMP_FINAL_MODULE `llvm-config --cppflags --ldflags --libs core jit native irreader` -o toy-ir-gen
diff --git a/examples/Kaleidoscope/MCJIT/cached/toy-jit.cpp b/examples/Kaleidoscope/MCJIT/cached/toy-jit.cpp
index 77b7f001095af..3f3b133703b19 100644
--- a/examples/Kaleidoscope/MCJIT/cached/toy-jit.cpp
+++ b/examples/Kaleidoscope/MCJIT/cached/toy-jit.cpp
@@ -623,7 +623,8 @@ static PrototypeAST *ParseExtern() {
static Module *TheModule;
static FunctionPassManager *TheFPM;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -634,12 +635,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -699,8 +699,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -740,18 +739,17 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
-
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
-
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
// Emit then value.
@@ -778,9 +776,8 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
return PN;
@@ -821,8 +818,8 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -847,7 +844,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -861,13 +858,13 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -882,7 +879,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -905,7 +902,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -933,10 +930,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
// If F conflicted, there was already something named 'Name'. If it has a
@@ -994,7 +990,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1122,7 +1118,7 @@ double printlf() {
Module* parseInputIR(std::string InputFile) {
SMDiagnostic Err;
- Module *M = ParseIRFile(InputFile, Err, getGlobalContext());
+ Module *M = ParseIRFile(InputFile, Err, TheContext);
if (!M) {
Err.print("IR parsing failed: ", errs());
return NULL;
@@ -1137,7 +1133,7 @@ Module* parseInputIR(std::string InputFile) {
int main(int argc, char **argv) {
InitializeNativeTarget();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
cl::ParseCommandLineOptions(argc, argv,
"Kaleidoscope example program\n");
diff --git a/examples/Kaleidoscope/MCJIT/cached/toy.cpp b/examples/Kaleidoscope/MCJIT/cached/toy.cpp
index cc12abcc43169..2b9c3da921881 100644
--- a/examples/Kaleidoscope/MCJIT/cached/toy.cpp
+++ b/examples/Kaleidoscope/MCJIT/cached/toy.cpp
@@ -994,7 +994,8 @@ void MCJITHelper::dump()
//===----------------------------------------------------------------------===//
static MCJITHelper *TheHelper;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -1005,12 +1006,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -1066,8 +1066,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -1104,17 +1103,16 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -1142,8 +1140,7 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -1185,7 +1182,7 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -1211,7 +1208,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -1225,12 +1222,12 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -1246,7 +1243,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -1269,7 +1266,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1297,10 +1294,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
std::string FnName = MakeLegalFunctionName(Name);
@@ -1365,7 +1361,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1490,7 +1486,7 @@ double printlf() {
Module* parseInputIR(std::string InputFile) {
SMDiagnostic Err;
- Module *M = ParseIRFile(InputFile, Err, getGlobalContext());
+ Module *M = ParseIRFile(InputFile, Err, TheContext);
if (!M) {
Err.print("IR parsing failed: ", errs());
return NULL;
@@ -1512,7 +1508,7 @@ int main(int argc, char **argv) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
cl::ParseCommandLineOptions(argc, argv,
"Kaleidoscope example program\n");
diff --git a/examples/Kaleidoscope/MCJIT/complete/Makefile b/examples/Kaleidoscope/MCJIT/complete/Makefile
deleted file mode 100644
index 9e45d17a69f01..0000000000000
--- a/examples/Kaleidoscope/MCJIT/complete/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-all: toy
-
-toy : toy.cpp
- clang++ toy.cpp -g -O3 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --libs core jit mcjit native irreader` -o toy
diff --git a/examples/Kaleidoscope/MCJIT/complete/toy.cpp b/examples/Kaleidoscope/MCJIT/complete/toy.cpp
index c78ec35fa0b3d..40a00693e8cb0 100644
--- a/examples/Kaleidoscope/MCJIT/complete/toy.cpp
+++ b/examples/Kaleidoscope/MCJIT/complete/toy.cpp
@@ -1066,7 +1066,8 @@ void MCJITHelper::dump()
//===----------------------------------------------------------------------===//
static BaseHelper *TheHelper;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -1077,12 +1078,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -1140,8 +1140,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -1182,17 +1181,16 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -1220,8 +1218,7 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -1263,7 +1260,7 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -1289,7 +1286,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -1303,12 +1300,12 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -1324,7 +1321,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -1347,7 +1344,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1375,10 +1372,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
std::string FnName;
FnName = MakeLegalFunctionName(Name);
@@ -1443,7 +1439,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1565,7 +1561,7 @@ int main(int argc, char **argv) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
cl::ParseCommandLineOptions(argc, argv,
"Kaleidoscope example program\n");
diff --git a/examples/Kaleidoscope/MCJIT/initial/Makefile b/examples/Kaleidoscope/MCJIT/initial/Makefile
deleted file mode 100644
index 2989832d3c796..0000000000000
--- a/examples/Kaleidoscope/MCJIT/initial/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-all: toy-mcjit
-
-toy-mcjit : toy.cpp
- clang++ toy.cpp -g -O3 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --libs core mcjit native` -o toy-mcjit
diff --git a/examples/Kaleidoscope/MCJIT/initial/toy.cpp b/examples/Kaleidoscope/MCJIT/initial/toy.cpp
index 9455946087d13..1e476aef7862f 100644
--- a/examples/Kaleidoscope/MCJIT/initial/toy.cpp
+++ b/examples/Kaleidoscope/MCJIT/initial/toy.cpp
@@ -852,7 +852,8 @@ void MCJITHelper::dump()
//===----------------------------------------------------------------------===//
static MCJITHelper *TheHelper;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -863,12 +864,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -924,8 +924,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -962,17 +961,16 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -1000,8 +998,7 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -1043,7 +1040,7 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -1069,7 +1066,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -1083,12 +1080,12 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -1104,7 +1101,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -1127,7 +1124,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1155,10 +1152,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
std::string FnName = MakeLegalFunctionName(Name);
@@ -1223,7 +1219,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1349,7 +1345,7 @@ int main() {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
// Install standard binary operators.
// 1 is lowest precedence.
diff --git a/examples/Kaleidoscope/MCJIT/lazy/Makefile b/examples/Kaleidoscope/MCJIT/lazy/Makefile
deleted file mode 100644
index 21cbc18d6e24f..0000000000000
--- a/examples/Kaleidoscope/MCJIT/lazy/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-all: toy-mcjit toy-jit
-
-toy-mcjit : toy.cpp
- clang++ toy.cpp -g -O3 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --libs core mcjit native` -o toy-mcjit
-
-toy-jit : toy-jit.cpp
- clang++ toy-jit.cpp -g -O3 -rdynamic `llvm-config --cppflags --ldflags --libs core jit native` -o toy-jit
diff --git a/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp b/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp
index 07adbd45014e8..f0c5ad5a46d7f 100644
--- a/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp
+++ b/examples/Kaleidoscope/MCJIT/lazy/toy-jit.cpp
@@ -608,7 +608,8 @@ static PrototypeAST *ParseExtern() {
static Module *TheModule;
static FunctionPassManager *TheFPM;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -619,12 +620,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -681,8 +681,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -722,18 +721,17 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
-
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
-
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
+
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
// Emit then value.
@@ -760,9 +758,8 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
return PN;
@@ -803,8 +800,8 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
+
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -829,7 +826,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -843,13 +840,13 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
+
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -864,7 +861,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -887,7 +884,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -915,10 +912,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
// If F conflicted, there was already something named 'Name'. If it has a
@@ -976,7 +972,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1104,7 +1100,7 @@ double printlf() {
int main(int argc, char **argv) {
InitializeNativeTarget();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
// Install standard binary operators.
// 1 is lowest precedence.
diff --git a/examples/Kaleidoscope/MCJIT/lazy/toy.cpp b/examples/Kaleidoscope/MCJIT/lazy/toy.cpp
index 14d758cfa7909..37339b60b4483 100644
--- a/examples/Kaleidoscope/MCJIT/lazy/toy.cpp
+++ b/examples/Kaleidoscope/MCJIT/lazy/toy.cpp
@@ -892,7 +892,8 @@ void MCJITHelper::dump()
//===----------------------------------------------------------------------===//
static MCJITHelper *TheHelper;
-static IRBuilder<> Builder(getGlobalContext());
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
@@ -903,12 +904,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
const std::string &VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
- VarName.c_str());
+ return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, VarName.c_str());
}
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::Codegen() {
@@ -964,8 +964,7 @@ Value *BinaryExprAST::Codegen() {
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default: break;
}
@@ -1002,17 +1001,16 @@ Value *IfExprAST::Codegen() {
if (CondV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
- CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "ifcond");
+ CondV = Builder.CreateFCmpONE(
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -1040,8 +1038,7 @@ Value *IfExprAST::Codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -1083,7 +1080,7 @@ Value *ForExprAST::Codegen() {
// Make the new basic block for the loop header, inserting after current
// block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -1109,7 +1106,7 @@ Value *ForExprAST::Codegen() {
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
// Compute the end condition.
@@ -1123,12 +1120,12 @@ Value *ForExprAST::Codegen() {
Builder.CreateStore(NextVar, Alloca);
// Convert condition to a bool by comparing equal to 0.0.
- EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
+ EndCond = Builder.CreateFCmpONE(
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock *AfterBB =
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -1144,7 +1141,7 @@ Value *ForExprAST::Codegen() {
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Value *VarExprAST::Codegen() {
@@ -1167,7 +1164,7 @@ Value *VarExprAST::Codegen() {
InitVal = Init->Codegen();
if (InitVal == 0) return 0;
} else { // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
+ InitVal = ConstantFP::get(TheContext, APFloat(0.0));
}
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
@@ -1195,10 +1192,9 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
+ FunctionType *FT =
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
std::string FnName = MakeLegalFunctionName(Name);
@@ -1263,7 +1259,7 @@ Function *FunctionAST::Codegen() {
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Add all arguments to the symbol table and create their allocas.
@@ -1390,7 +1386,7 @@ int main() {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
- LLVMContext &Context = getGlobalContext();
+ LLVMContext &Context = TheContext;
// Install standard binary operators.
// 1 is lowest precedence.
diff --git a/examples/Kaleidoscope/Makefile b/examples/Kaleidoscope/Makefile
deleted file mode 100644
index 8c3b1e31d9bbe..0000000000000
--- a/examples/Kaleidoscope/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/Kaleidoscope/Makefile ----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL=../..
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS:= Chapter2 Chapter3 Chapter4 Chapter5 Chapter6 Chapter7 Chapter8
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/Kaleidoscope/Orc/CMakeLists.txt b/examples/Kaleidoscope/Orc/CMakeLists.txt
deleted file mode 100644
index 5aa04543dc687..0000000000000
--- a/examples/Kaleidoscope/Orc/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_subdirectory(initial)
-add_subdirectory(lazy_codegen)
-add_subdirectory(lazy_irgen)
-add_subdirectory(fully_lazy)
diff --git a/examples/Kaleidoscope/Orc/fully_lazy/CMakeLists.txt b/examples/Kaleidoscope/Orc/fully_lazy/CMakeLists.txt
deleted file mode 100644
index abb0428a152ea..0000000000000
--- a/examples/Kaleidoscope/Orc/fully_lazy/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- Core
- ExecutionEngine
- Object
- OrcJIT
- RuntimeDyld
- Support
- native
- )
-
-add_kaleidoscope_chapter(Kaleidoscope-Orc-fully_lazy
- toy.cpp
- )
diff --git a/examples/Kaleidoscope/Orc/fully_lazy/Makefile b/examples/Kaleidoscope/Orc/fully_lazy/Makefile
deleted file mode 100644
index 5536314f2a309..0000000000000
--- a/examples/Kaleidoscope/Orc/fully_lazy/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-UNAME := $(shell uname -s)
-
-ifeq ($(UNAME),Darwin)
- CXX := xcrun --sdk macosx clang++
-else
- CXX := clang++
-endif
-
-LLVM_CXXFLAGS := $(shell llvm-config --cxxflags)
-LLVM_LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core orcjit native)
-
-toy: toy.cpp
- $(CXX) $(LLVM_CXXFLAGS) -Wall -std=c++11 -g -O0 -rdynamic -fno-rtti -o toy toy.cpp $(LLVM_LDFLAGS)
-
-.PHONY: clean
-clean:
- rm -f toy
diff --git a/examples/Kaleidoscope/Orc/fully_lazy/README.txt b/examples/Kaleidoscope/Orc/fully_lazy/README.txt
deleted file mode 100644
index c0189319f2c55..0000000000000
--- a/examples/Kaleidoscope/Orc/fully_lazy/README.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-//===----------------------------------------------------------------------===/
-// Kaleidoscope with Orc - Lazy IRGen Version
-//===----------------------------------------------------------------------===//
-
-This version of Kaleidoscope with Orc demonstrates fully lazy IR-generation.
-Building on the lazy-irgen version of the tutorial, this version injects JIT
-callbacks to defer the bulk of IR-generation and code-generation of functions until
-they are first called.
-
-When a function definition is entered, a JIT callback is created and a stub
-function is built that will call the body of the function indirectly. The body of
-the function is *not* IRGen'd at this point. Instead, the function pointer for
-the indirect call is initialized to point at the JIT callback, and the compile
-action for the callback is initialized with a lambda that IRGens the body of the
-function and adds it to the JIT. The function pointer is updated by the JIT
-callback's update action to point at the newly emitted function body, so future
-calls to the stub will go straight to the body, not through the JIT.
-
-This directory contains a Makefile that allows the code to be built in a
-standalone manner, independent of the larger LLVM build infrastructure. To build
-the program you will need to have 'clang++' and 'llvm-config' in your path.
diff --git a/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp b/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp
deleted file mode 100644
index 0371a3f76f69c..0000000000000
--- a/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp
+++ /dev/null
@@ -1,1440 +0,0 @@
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
-#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
-#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Transforms/Scalar.h"
-#include <cctype>
-#include <iomanip>
-#include <iostream>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::orc;
-
-//===----------------------------------------------------------------------===//
-// Lexer
-//===----------------------------------------------------------------------===//
-
-// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
-// of these for known things.
-enum Token {
- tok_eof = -1,
-
- // commands
- tok_def = -2, tok_extern = -3,
-
- // primary
- tok_identifier = -4, tok_number = -5,
-
- // control
- tok_if = -6, tok_then = -7, tok_else = -8,
- tok_for = -9, tok_in = -10,
-
- // operators
- tok_binary = -11, tok_unary = -12,
-
- // var definition
- tok_var = -13
-};
-
-static std::string IdentifierStr; // Filled in if tok_identifier
-static double NumVal; // Filled in if tok_number
-
-/// gettok - Return the next token from standard input.
-static int gettok() {
- static int LastChar = ' ';
-
- // Skip any whitespace.
- while (isspace(LastChar))
- LastChar = getchar();
-
- if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
- IdentifierStr = LastChar;
- while (isalnum((LastChar = getchar())))
- IdentifierStr += LastChar;
-
- if (IdentifierStr == "def") return tok_def;
- if (IdentifierStr == "extern") return tok_extern;
- if (IdentifierStr == "if") return tok_if;
- if (IdentifierStr == "then") return tok_then;
- if (IdentifierStr == "else") return tok_else;
- if (IdentifierStr == "for") return tok_for;
- if (IdentifierStr == "in") return tok_in;
- if (IdentifierStr == "binary") return tok_binary;
- if (IdentifierStr == "unary") return tok_unary;
- if (IdentifierStr == "var") return tok_var;
- return tok_identifier;
- }
-
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
- std::string NumStr;
- do {
- NumStr += LastChar;
- LastChar = getchar();
- } while (isdigit(LastChar) || LastChar == '.');
-
- NumVal = strtod(NumStr.c_str(), nullptr);
- return tok_number;
- }
-
- if (LastChar == '#') {
- // Comment until end of line.
- do LastChar = getchar();
- while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
-
- if (LastChar != EOF)
- return gettok();
- }
-
- // Check for end of file. Don't eat the EOF.
- if (LastChar == EOF)
- return tok_eof;
-
- // Otherwise, just return the character as its ascii value.
- int ThisChar = LastChar;
- LastChar = getchar();
- return ThisChar;
-}
-
-//===----------------------------------------------------------------------===//
-// Abstract Syntax Tree (aka Parse Tree)
-//===----------------------------------------------------------------------===//
-
-class IRGenContext;
-
-/// ExprAST - Base class for all expression nodes.
-struct ExprAST {
- virtual ~ExprAST() {}
- virtual Value *IRGen(IRGenContext &C) const = 0;
-};
-
-/// NumberExprAST - Expression class for numeric literals like "1.0".
-struct NumberExprAST : public ExprAST {
- NumberExprAST(double Val) : Val(Val) {}
- Value *IRGen(IRGenContext &C) const override;
-
- double Val;
-};
-
-/// VariableExprAST - Expression class for referencing a variable, like "a".
-struct VariableExprAST : public ExprAST {
- VariableExprAST(std::string Name) : Name(std::move(Name)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::string Name;
-};
-
-/// UnaryExprAST - Expression class for a unary operator.
-struct UnaryExprAST : public ExprAST {
- UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
- : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Opcode;
- std::unique_ptr<ExprAST> Operand;
-};
-
-/// BinaryExprAST - Expression class for a binary operator.
-struct BinaryExprAST : public ExprAST {
- BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
- std::unique_ptr<ExprAST> RHS)
- : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Op;
- std::unique_ptr<ExprAST> LHS, RHS;
-};
-
-/// CallExprAST - Expression class for function calls.
-struct CallExprAST : public ExprAST {
- CallExprAST(std::string CalleeName,
- std::vector<std::unique_ptr<ExprAST>> Args)
- : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string CalleeName;
- std::vector<std::unique_ptr<ExprAST>> Args;
-};
-
-/// IfExprAST - Expression class for if/then/else.
-struct IfExprAST : public ExprAST {
- IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
- std::unique_ptr<ExprAST> Else)
- : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::unique_ptr<ExprAST> Cond, Then, Else;
-};
-
-/// ForExprAST - Expression class for for/in.
-struct ForExprAST : public ExprAST {
- ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start,
- std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
- std::unique_ptr<ExprAST> Body)
- : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)),
- Step(std::move(Step)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string VarName;
- std::unique_ptr<ExprAST> Start, End, Step, Body;
-};
-
-/// VarExprAST - Expression class for var/in
-struct VarExprAST : public ExprAST {
- typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding;
- typedef std::vector<Binding> BindingList;
-
- VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body)
- : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- BindingList VarBindings;
- std::unique_ptr<ExprAST> Body;
-};
-
-/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
-struct PrototypeAST {
- PrototypeAST(std::string Name, std::vector<std::string> Args,
- bool IsOperator = false, unsigned Precedence = 0)
- : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Precedence) {}
-
- Function *IRGen(IRGenContext &C) const;
- void CreateArgumentAllocas(Function *F, IRGenContext &C);
-
- bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
- bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
-
- char getOperatorName() const {
- assert(isUnaryOp() || isBinaryOp());
- return Name[Name.size()-1];
- }
-
- std::string Name;
- std::vector<std::string> Args;
- bool IsOperator;
- unsigned Precedence; // Precedence if a binary op.
-};
-
-/// FunctionAST - This class represents a function definition itself.
-struct FunctionAST {
- FunctionAST(std::unique_ptr<PrototypeAST> Proto,
- std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
-
- Function *IRGen(IRGenContext &C) const;
-
- std::unique_ptr<PrototypeAST> Proto;
- std::unique_ptr<ExprAST> Body;
-};
-
-//===----------------------------------------------------------------------===//
-// Parser
-//===----------------------------------------------------------------------===//
-
-/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
-/// token the parser is looking at. getNextToken reads another token from the
-/// lexer and updates CurTok with its results.
-static int CurTok;
-static int getNextToken() {
- return CurTok = gettok();
-}
-
-/// BinopPrecedence - This holds the precedence for each binary operator that is
-/// defined.
-static std::map<char, int> BinopPrecedence;
-
-/// GetTokPrecedence - Get the precedence of the pending binary operator token.
-static int GetTokPrecedence() {
- if (!isascii(CurTok))
- return -1;
-
- // Make sure it's a declared binop.
- int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
- return TokPrec;
-}
-
-template <typename T>
-std::unique_ptr<T> ErrorU(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-template <typename T>
-T* ErrorP(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-static std::unique_ptr<ExprAST> ParseExpression();
-
-/// identifierexpr
-/// ::= identifier
-/// ::= identifier '(' expression* ')'
-static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
- std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
- if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(IdName);
-
- // Call.
- getNextToken(); // eat (
- std::vector<std::unique_ptr<ExprAST>> Args;
- if (CurTok != ')') {
- while (1) {
- auto Arg = ParseExpression();
- if (!Arg) return nullptr;
- Args.push_back(std::move(Arg));
-
- if (CurTok == ')') break;
-
- if (CurTok != ',')
- return ErrorU<CallExprAST>("Expected ')' or ',' in argument list");
- getNextToken();
- }
- }
-
- // Eat the ')'.
- getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-
-/// numberexpr ::= number
-static std::unique_ptr<NumberExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return Result;
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return ErrorU<ExprAST>("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
-/// ifexpr ::= 'if' expression 'then' expression 'else' expression
-static std::unique_ptr<ExprAST> ParseIfExpr() {
- getNextToken(); // eat the if.
-
- // condition.
- auto Cond = ParseExpression();
- if (!Cond)
- return nullptr;
-
- if (CurTok != tok_then)
- return ErrorU<ExprAST>("expected then");
- getNextToken(); // eat the then
-
- auto Then = ParseExpression();
- if (!Then)
- return nullptr;
-
- if (CurTok != tok_else)
- return ErrorU<ExprAST>("expected else");
-
- getNextToken();
-
- auto Else = ParseExpression();
- if (!Else)
- return nullptr;
-
- return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
- std::move(Else));
-}
-
-/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
-static std::unique_ptr<ForExprAST> ParseForExpr() {
- getNextToken(); // eat the for.
-
- if (CurTok != tok_identifier)
- return ErrorU<ForExprAST>("expected identifier after for");
-
- std::string IdName = IdentifierStr;
- getNextToken(); // eat identifier.
-
- if (CurTok != '=')
- return ErrorU<ForExprAST>("expected '=' after for");
- getNextToken(); // eat '='.
-
- auto Start = ParseExpression();
- if (!Start)
- return nullptr;
- if (CurTok != ',')
- return ErrorU<ForExprAST>("expected ',' after for start value");
- getNextToken();
-
- auto End = ParseExpression();
- if (!End)
- return nullptr;
-
- // The step value is optional.
- std::unique_ptr<ExprAST> Step;
- if (CurTok == ',') {
- getNextToken();
- Step = ParseExpression();
- if (!Step)
- return nullptr;
- }
-
- if (CurTok != tok_in)
- return ErrorU<ForExprAST>("expected 'in' after for");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (Body)
- return nullptr;
-
- return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
- std::move(Step), std::move(Body));
-}
-
-/// varexpr ::= 'var' identifier ('=' expression)?
-// (',' identifier ('=' expression)?)* 'in' expression
-static std::unique_ptr<VarExprAST> ParseVarExpr() {
- getNextToken(); // eat the var.
-
- VarExprAST::BindingList VarBindings;
-
- // At least one variable name is required.
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier after var");
-
- while (1) {
- std::string Name = IdentifierStr;
- getNextToken(); // eat identifier.
-
- // Read the optional initializer.
- std::unique_ptr<ExprAST> Init;
- if (CurTok == '=') {
- getNextToken(); // eat the '='.
-
- Init = ParseExpression();
- if (!Init)
- return nullptr;
- }
-
- VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init)));
-
- // End of var list, exit loop.
- if (CurTok != ',') break;
- getNextToken(); // eat the ','.
-
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier list after var");
- }
-
- // At this point, we have to have 'in'.
- if (CurTok != tok_in)
- return ErrorU<VarExprAST>("expected 'in' keyword after 'var'");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (!Body)
- return nullptr;
-
- return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body));
-}
-
-/// primary
-/// ::= identifierexpr
-/// ::= numberexpr
-/// ::= parenexpr
-/// ::= ifexpr
-/// ::= forexpr
-/// ::= varexpr
-static std::unique_ptr<ExprAST> ParsePrimary() {
- switch (CurTok) {
- default: return ErrorU<ExprAST>("unknown token when expecting an expression");
- case tok_identifier: return ParseIdentifierExpr();
- case tok_number: return ParseNumberExpr();
- case '(': return ParseParenExpr();
- case tok_if: return ParseIfExpr();
- case tok_for: return ParseForExpr();
- case tok_var: return ParseVarExpr();
- }
-}
-
-/// unary
-/// ::= primary
-/// ::= '!' unary
-static std::unique_ptr<ExprAST> ParseUnary() {
- // If the current token is not an operator, it must be a primary expr.
- if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
- return ParsePrimary();
-
- // If this is a unary operator, read it.
- int Opc = CurTok;
- getNextToken();
- if (auto Operand = ParseUnary())
- return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
- return nullptr;
-}
-
-/// binoprhs
-/// ::= ('+' unary)*
-static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
- std::unique_ptr<ExprAST> LHS) {
- // If this is a binop, find its precedence.
- while (1) {
- int TokPrec = GetTokPrecedence();
-
- // If this is a binop that binds at least as tightly as the current binop,
- // consume it, otherwise we are done.
- if (TokPrec < ExprPrec)
- return LHS;
-
- // Okay, we know this is a binop.
- int BinOp = CurTok;
- getNextToken(); // eat binop
-
- // Parse the unary expression after the binary operator.
- auto RHS = ParseUnary();
- if (!RHS)
- return nullptr;
-
- // If BinOp binds less tightly with RHS than the operator after RHS, let
- // the pending operator take RHS as its LHS.
- int NextPrec = GetTokPrecedence();
- if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
- if (!RHS)
- return nullptr;
- }
-
- // Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
- }
-}
-
-/// expression
-/// ::= unary binoprhs
-///
-static std::unique_ptr<ExprAST> ParseExpression() {
- auto LHS = ParseUnary();
- if (!LHS)
- return nullptr;
-
- return ParseBinOpRHS(0, std::move(LHS));
-}
-
-/// prototype
-/// ::= id '(' id* ')'
-/// ::= binary LETTER number? (id, id)
-/// ::= unary LETTER (id)
-static std::unique_ptr<PrototypeAST> ParsePrototype() {
- std::string FnName;
-
- unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
- unsigned BinaryPrecedence = 30;
-
- switch (CurTok) {
- default:
- return ErrorU<PrototypeAST>("Expected function name in prototype");
- case tok_identifier:
- FnName = IdentifierStr;
- Kind = 0;
- getNextToken();
- break;
- case tok_unary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected unary operator");
- FnName = "unary";
- FnName += (char)CurTok;
- Kind = 1;
- getNextToken();
- break;
- case tok_binary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected binary operator");
- FnName = "binary";
- FnName += (char)CurTok;
- Kind = 2;
- getNextToken();
-
- // Read the precedence if present.
- if (CurTok == tok_number) {
- if (NumVal < 1 || NumVal > 100)
- return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100");
- BinaryPrecedence = (unsigned)NumVal;
- getNextToken();
- }
- break;
- }
-
- if (CurTok != '(')
- return ErrorU<PrototypeAST>("Expected '(' in prototype");
-
- std::vector<std::string> ArgNames;
- while (getNextToken() == tok_identifier)
- ArgNames.push_back(IdentifierStr);
- if (CurTok != ')')
- return ErrorU<PrototypeAST>("Expected ')' in prototype");
-
- // success.
- getNextToken(); // eat ')'.
-
- // Verify right number of names for operator.
- if (Kind && ArgNames.size() != Kind)
- return ErrorU<PrototypeAST>("Invalid number of operands for operator");
-
- return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
- BinaryPrecedence);
-}
-
-/// definition ::= 'def' prototype expression
-static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
- auto Proto = ParsePrototype();
- if (!Proto)
- return nullptr;
-
- if (auto Body = ParseExpression())
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body));
- return nullptr;
-}
-
-/// toplevelexpr ::= expression
-static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- if (auto E = ParseExpression()) {
- // Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
- }
- return nullptr;
-}
-
-/// external ::= 'extern' prototype
-static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
- return ParsePrototype();
-}
-
-//===----------------------------------------------------------------------===//
-// Code Generation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Obviously we can do better than this
-std::string GenerateUniqueName(const std::string &Root) {
- static int i = 0;
- std::ostringstream NameStream;
- NameStream << Root << ++i;
- return NameStream.str();
-}
-
-std::string MakeLegalFunctionName(std::string Name)
-{
- std::string NewName;
- assert(!Name.empty() && "Base name must not be empty");
-
- // Start with what we have
- NewName = Name;
-
- // Look for a numberic first character
- if (NewName.find_first_of("0123456789") == 0) {
- NewName.insert(0, 1, 'n');
- }
-
- // Replace illegal characters with their ASCII equivalent
- std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- size_t pos;
- while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {
- std::ostringstream NumStream;
- NumStream << (int)NewName.at(pos);
- NewName = NewName.replace(pos, 1, NumStream.str());
- }
-
- return NewName;
-}
-
-class SessionContext {
-public:
- SessionContext(LLVMContext &C)
- : Context(C), TM(EngineBuilder().selectTarget()) {}
- LLVMContext& getLLVMContext() const { return Context; }
- TargetMachine& getTarget() { return *TM; }
- void addPrototypeAST(std::unique_ptr<PrototypeAST> P);
- PrototypeAST* getPrototypeAST(const std::string &Name);
-private:
- typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap;
-
- LLVMContext &Context;
- std::unique_ptr<TargetMachine> TM;
-
- PrototypeMap Prototypes;
-};
-
-void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) {
- Prototypes[P->Name] = std::move(P);
-}
-
-PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) {
- PrototypeMap::iterator I = Prototypes.find(Name);
- if (I != Prototypes.end())
- return I->second.get();
- return nullptr;
-}
-
-class IRGenContext {
-public:
-
- IRGenContext(SessionContext &S)
- : Session(S),
- M(new Module(GenerateUniqueName("jit_module_"),
- Session.getLLVMContext())),
- Builder(Session.getLLVMContext()) {
- M->setDataLayout(Session.getTarget().createDataLayout());
- }
-
- SessionContext& getSession() { return Session; }
- Module& getM() const { return *M; }
- std::unique_ptr<Module> takeM() { return std::move(M); }
- IRBuilder<>& getBuilder() { return Builder; }
- LLVMContext& getLLVMContext() { return Session.getLLVMContext(); }
- Function* getPrototype(const std::string &Name);
-
- std::map<std::string, AllocaInst*> NamedValues;
-private:
- SessionContext &Session;
- std::unique_ptr<Module> M;
- IRBuilder<> Builder;
-};
-
-Function* IRGenContext::getPrototype(const std::string &Name) {
- if (Function *ExistingProto = M->getFunction(Name))
- return ExistingProto;
- if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name))
- return ProtoAST->IRGen(*this);
- return nullptr;
-}
-
-/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
-/// the function. This is used for mutable variables etc.
-static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
- const std::string &VarName) {
- IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
- TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
-}
-
-Value *NumberExprAST::IRGen(IRGenContext &C) const {
- return ConstantFP::get(C.getLLVMContext(), APFloat(Val));
-}
-
-Value *VariableExprAST::IRGen(IRGenContext &C) const {
- // Look this variable up in the function.
- Value *V = C.NamedValues[Name];
-
- if (!V)
- return ErrorP<Value>("Unknown variable name '" + Name + "'");
-
- // Load the value.
- return C.getBuilder().CreateLoad(V, Name.c_str());
-}
-
-Value *UnaryExprAST::IRGen(IRGenContext &C) const {
- if (Value *OperandV = Operand->IRGen(C)) {
- std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode);
- if (Function *F = C.getPrototype(FnName))
- return C.getBuilder().CreateCall(F, OperandV, "unop");
- return ErrorP<Value>("Unknown unary operator");
- }
-
- // Could not codegen operand - return null.
- return nullptr;
-}
-
-Value *BinaryExprAST::IRGen(IRGenContext &C) const {
- // Special case '=' because we don't want to emit the LHS as an expression.
- if (Op == '=') {
- // Assignment requires the LHS to be an identifier.
- auto &LHSVar = static_cast<VariableExprAST &>(*LHS);
- // Codegen the RHS.
- Value *Val = RHS->IRGen(C);
- if (!Val) return nullptr;
-
- // Look up the name.
- if (auto Variable = C.NamedValues[LHSVar.Name]) {
- C.getBuilder().CreateStore(Val, Variable);
- return Val;
- }
- return ErrorP<Value>("Unknown variable name");
- }
-
- Value *L = LHS->IRGen(C);
- Value *R = RHS->IRGen(C);
- if (!L || !R) return nullptr;
-
- switch (Op) {
- case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp");
- case '-': return C.getBuilder().CreateFSub(L, R, "subtmp");
- case '*': return C.getBuilder().CreateFMul(L, R, "multmp");
- case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp");
- case '<':
- L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp");
- // Convert bool 0/1 to double 0.0 or 1.0
- return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
- default: break;
- }
-
- // If it wasn't a builtin binary operator, it must be a user defined one. Emit
- // a call to it.
- std::string FnName = MakeLegalFunctionName(std::string("binary")+Op);
- if (Function *F = C.getPrototype(FnName)) {
- Value *Ops[] = { L, R };
- return C.getBuilder().CreateCall(F, Ops, "binop");
- }
-
- return ErrorP<Value>("Unknown binary operator");
-}
-
-Value *CallExprAST::IRGen(IRGenContext &C) const {
- // Look up the name in the global module table.
- if (auto CalleeF = C.getPrototype(CalleeName)) {
- // If argument mismatch error.
- if (CalleeF->arg_size() != Args.size())
- return ErrorP<Value>("Incorrect # arguments passed");
-
- std::vector<Value*> ArgsV;
- for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- ArgsV.push_back(Args[i]->IRGen(C));
- if (!ArgsV.back()) return nullptr;
- }
-
- return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp");
- }
-
- return ErrorP<Value>("Unknown function referenced");
-}
-
-Value *IfExprAST::IRGen(IRGenContext &C) const {
- Value *CondV = Cond->IRGen(C);
- if (!CondV) return nullptr;
-
- // Convert condition to a bool by comparing equal to 0.0.
- ConstantFP *FPZero =
- ConstantFP::get(C.getLLVMContext(), APFloat(0.0));
- CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond");
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create blocks for the then and else cases. Insert the 'then' block at the
- // end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont");
-
- C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB);
-
- // Emit then value.
- C.getBuilder().SetInsertPoint(ThenBB);
-
- Value *ThenV = Then->IRGen(C);
- if (!ThenV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
- ThenBB = C.getBuilder().GetInsertBlock();
-
- // Emit else block.
- TheFunction->getBasicBlockList().push_back(ElseBB);
- C.getBuilder().SetInsertPoint(ElseBB);
-
- Value *ElseV = Else->IRGen(C);
- if (!ElseV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
- ElseBB = C.getBuilder().GetInsertBlock();
-
- // Emit merge block.
- TheFunction->getBasicBlockList().push_back(MergeBB);
- C.getBuilder().SetInsertPoint(MergeBB);
- PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
- PN->addIncoming(ThenV, ThenBB);
- PN->addIncoming(ElseV, ElseBB);
- return PN;
-}
-
-Value *ForExprAST::IRGen(IRGenContext &C) const {
- // Output this as:
- // var = alloca double
- // ...
- // start = startexpr
- // store start -> var
- // goto loop
- // loop:
- // ...
- // bodyexpr
- // ...
- // loopend:
- // step = stepexpr
- // endcond = endexpr
- //
- // curvar = load var
- // nextvar = curvar + step
- // store nextvar -> var
- // br endcond, loop, endloop
- // outloop:
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create an alloca for the variable in the entry block.
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
-
- // Emit the start code first, without 'variable' in scope.
- Value *StartVal = Start->IRGen(C);
- if (!StartVal) return nullptr;
-
- // Store the value into the alloca.
- C.getBuilder().CreateStore(StartVal, Alloca);
-
- // Make the new basic block for the loop header, inserting after current
- // block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
- // Insert an explicit fall through from the current block to the LoopBB.
- C.getBuilder().CreateBr(LoopBB);
-
- // Start insertion in LoopBB.
- C.getBuilder().SetInsertPoint(LoopBB);
-
- // Within the loop, the variable is defined equal to the PHI node. If it
- // shadows an existing variable, we have to restore it, so save it now.
- AllocaInst *OldVal = C.NamedValues[VarName];
- C.NamedValues[VarName] = Alloca;
-
- // Emit the body of the loop. This, like any other expr, can change the
- // current BB. Note that we ignore the value computed by the body, but don't
- // allow an error.
- if (!Body->IRGen(C))
- return nullptr;
-
- // Emit the step value.
- Value *StepVal;
- if (Step) {
- StepVal = Step->IRGen(C);
- if (!StepVal) return nullptr;
- } else {
- // If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
- }
-
- // Compute the end condition.
- Value *EndCond = End->IRGen(C);
- if (!EndCond) return nullptr;
-
- // Reload, increment, and restore the alloca. This handles the case where
- // the body of the loop mutates the variable.
- Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str());
- Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar");
- C.getBuilder().CreateStore(NextVar, Alloca);
-
- // Convert condition to a bool by comparing equal to 0.0.
- EndCond = C.getBuilder().CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
- // Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
- // Insert the conditional branch into the end of LoopEndBB.
- C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB);
-
- // Any new code will be inserted in AfterBB.
- C.getBuilder().SetInsertPoint(AfterBB);
-
- // Restore the unshadowed variable.
- if (OldVal)
- C.NamedValues[VarName] = OldVal;
- else
- C.NamedValues.erase(VarName);
-
- // for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
-}
-
-Value *VarExprAST::IRGen(IRGenContext &C) const {
- std::vector<AllocaInst *> OldBindings;
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Register all variables and emit their initializer.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) {
- auto &VarName = VarBindings[i].first;
- auto &Init = VarBindings[i].second;
-
- // Emit the initializer before adding the variable to scope, this prevents
- // the initializer from referencing the variable itself, and permits stuff
- // like this:
- // var a = 1 in
- // var a = a in ... # refers to outer 'a'.
- Value *InitVal;
- if (Init) {
- InitVal = Init->IRGen(C);
- if (!InitVal) return nullptr;
- } else // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
-
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- C.getBuilder().CreateStore(InitVal, Alloca);
-
- // Remember the old variable binding so that we can restore the binding when
- // we unrecurse.
- OldBindings.push_back(C.NamedValues[VarName]);
-
- // Remember this binding.
- C.NamedValues[VarName] = Alloca;
- }
-
- // Codegen the body, now that all vars are in scope.
- Value *BodyVal = Body->IRGen(C);
- if (!BodyVal) return nullptr;
-
- // Pop all our variables from scope.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i)
- C.NamedValues[VarBindings[i].first] = OldBindings[i];
-
- // Return the body computation.
- return BodyVal;
-}
-
-Function *PrototypeAST::IRGen(IRGenContext &C) const {
- std::string FnName = MakeLegalFunctionName(Name);
-
- // Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
- Function *F = Function::Create(FT, Function::ExternalLinkage, FnName,
- &C.getM());
-
- // If F conflicted, there was already something named 'FnName'. If it has a
- // body, don't allow redefinition or reextern.
- if (F->getName() != FnName) {
- // Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = C.getM().getFunction(Name);
-
- // If F already has a body, reject this.
- if (!F->empty()) {
- ErrorP<Function>("redefinition of function");
- return nullptr;
- }
-
- // If F took a different number of args, reject.
- if (F->arg_size() != Args.size()) {
- ErrorP<Function>("redefinition of function with different # args");
- return nullptr;
- }
- }
-
- // Set names for all arguments.
- unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
- ++AI, ++Idx)
- AI->setName(Args[Idx]);
-
- return F;
-}
-
-/// CreateArgumentAllocas - Create an alloca for each argument and register the
-/// argument in the symbol table so that references to it will succeed.
-void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) {
- Function::arg_iterator AI = F->arg_begin();
- for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
- // Create an alloca for this variable.
- AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
-
- // Store the initial value into the alloca.
- C.getBuilder().CreateStore(&*AI, Alloca);
-
- // Add arguments to variable symbol table.
- C.NamedValues[Args[Idx]] = Alloca;
- }
-}
-
-Function *FunctionAST::IRGen(IRGenContext &C) const {
- C.NamedValues.clear();
-
- Function *TheFunction = Proto->IRGen(C);
- if (!TheFunction)
- return nullptr;
-
- // If this is an operator, install it.
- if (Proto->isBinaryOp())
- BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence;
-
- // Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
- C.getBuilder().SetInsertPoint(BB);
-
- // Add all arguments to the symbol table and create their allocas.
- Proto->CreateArgumentAllocas(TheFunction, C);
-
- if (Value *RetVal = Body->IRGen(C)) {
- // Finish off the function.
- C.getBuilder().CreateRet(RetVal);
-
- // Validate the generated code, checking for consistency.
- verifyFunction(*TheFunction);
-
- return TheFunction;
- }
-
- // Error reading body, remove function.
- TheFunction->eraseFromParent();
-
- if (Proto->isBinaryOp())
- BinopPrecedence.erase(Proto->getOperatorName());
- return nullptr;
-}
-
-//===----------------------------------------------------------------------===//
-// Top-Level parsing and JIT Driver
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<llvm::Module> IRGen(SessionContext &S,
- const FunctionAST &F) {
- IRGenContext C(S);
- auto LF = F.IRGen(C);
- if (!LF)
- return nullptr;
-#ifndef MINIMAL_STDERR_OUTPUT
- fprintf(stderr, "Read function definition:");
- LF->dump();
-#endif
- return C.takeM();
-}
-
-template <typename T>
-static std::vector<T> singletonSet(T t) {
- std::vector<T> Vec;
- Vec.push_back(std::move(t));
- return Vec;
-}
-
-static void EarthShatteringKaboom() {
- fprintf(stderr, "Earth shattering kaboom.");
- exit(1);
-}
-
-class KaleidoscopeJIT {
-public:
- typedef ObjectLinkingLayer<> ObjLayerT;
- typedef IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
- typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT;
-
- KaleidoscopeJIT(SessionContext &Session)
- : Session(Session),
- CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())),
- LazyEmitLayer(CompileLayer),
- CompileCallbacks(reinterpret_cast<uintptr_t>(EarthShatteringKaboom)) {}
-
- std::string mangle(const std::string &Name) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name,
- Session.getTarget().createDataLayout());
- }
- return MangledName;
- }
-
- void addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
- std::cerr << "Adding AST: " << FnAST->Proto->Name << "\n";
- FunctionDefs[mangle(FnAST->Proto->Name)] = std::move(FnAST);
- }
-
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- // We need a memory manager to allocate memory and resolve symbols for this
- // new module. Create one that resolves symbols by looking back into the
- // JIT.
- auto Resolver = createLambdaResolver(
- [&](const std::string &Name) {
- // First try to find 'Name' within the JIT.
- if (auto Symbol = findSymbol(Name))
- return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
- Symbol.getFlags());
-
- // If we don't already have a definition of 'Name' then search
- // the ASTs.
- return searchFunctionASTs(Name);
- },
- [](const std::string &S) { return nullptr; } );
-
- return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- make_unique<SectionMemoryManager>(),
- std::move(Resolver));
- }
-
- void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
-
- JITSymbol findSymbol(const std::string &Name) {
- return LazyEmitLayer.findSymbol(Name, false);
- }
-
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
- return LazyEmitLayer.findSymbolIn(H, Name, false);
- }
-
- JITSymbol findUnmangledSymbol(const std::string &Name) {
- return findSymbol(mangle(Name));
- }
-
- JITSymbol findUnmangledSymbolIn(ModuleHandleT H, const std::string &Name) {
- return findSymbolIn(H, mangle(Name));
- }
-
-private:
-
- // This method searches the FunctionDefs map for a definition of 'Name'. If it
- // finds one it generates a stub for it and returns the address of the stub.
- RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) {
- auto DefI = FunctionDefs.find(Name);
- if (DefI == FunctionDefs.end())
- return nullptr;
-
- // Return the address of the stub.
- // Take the FunctionAST out of the map.
- auto FnAST = std::move(DefI->second);
- FunctionDefs.erase(DefI);
-
- // IRGen the AST, add it to the JIT, and return the address for it.
- auto H = irGenStub(std::move(FnAST));
- auto Sym = findSymbolIn(H, Name);
- return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
- }
-
- // This method will take the AST for a function definition and IR-gen a stub
- // for that function that will, on first call, IR-gen the actual body of the
- // function.
- ModuleHandleT irGenStub(std::unique_ptr<FunctionAST> FnAST) {
- // Step 1) IRGen a prototype for the stub. This will have the same type as
- // the function.
- IRGenContext C(Session);
- Function *F = FnAST->Proto->IRGen(C);
-
- // Step 2) Get a compile callback that can be used to compile the body of
- // the function. The resulting CallbackInfo type will let us set the
- // compile and update actions for the callback, and get a pointer to
- // the jit trampoline that we need to call to trigger those actions.
- auto CallbackInfo = CompileCallbacks.getCompileCallback();
-
- // Step 3) Create a stub that will indirectly call the body of this
- // function once it is compiled. Initially, set the function
- // pointer for the indirection to point at the trampoline.
- std::string BodyPtrName = (F->getName() + "$address").str();
- GlobalVariable *FunctionBodyPointer =
- createImplPointer(*F->getType(), *F->getParent(), BodyPtrName,
- createIRTypedAddress(*F->getFunctionType(),
- CallbackInfo.getAddress()));
- makeStub(*F, *FunctionBodyPointer);
-
- // Step 4) Add the module containing the stub to the JIT.
- auto StubH = addModule(C.takeM());
-
- // Step 5) Set the compile and update actions.
- //
- // The compile action will IRGen the function and add it to the JIT, then
- // request its address, which will trigger codegen. Since we don't need the
- // AST after this, we pass ownership of the AST into the compile action:
- // compile actions (and update actions) are deleted after they're run, so
- // this will free the AST for us.
- //
- // The update action will update FunctionBodyPointer to point at the newly
- // compiled function.
- std::shared_ptr<FunctionAST> Fn = std::move(FnAST);
- CallbackInfo.setCompileAction([this, Fn, BodyPtrName, StubH]() {
- auto H = addModule(IRGen(Session, *Fn));
- auto BodySym = findUnmangledSymbolIn(H, Fn->Proto->Name);
- auto BodyPtrSym = findUnmangledSymbolIn(StubH, BodyPtrName);
- assert(BodySym && "Missing function body.");
- assert(BodyPtrSym && "Missing function pointer.");
- auto BodyAddr = BodySym.getAddress();
- auto BodyPtr = reinterpret_cast<void*>(
- static_cast<uintptr_t>(BodyPtrSym.getAddress()));
- memcpy(BodyPtr, &BodyAddr, sizeof(uintptr_t));
- return BodyAddr;
- });
-
- return StubH;
- }
-
- SessionContext &Session;
- SectionMemoryManager CCMgrMemMgr;
- ObjLayerT ObjectLayer;
- CompileLayerT CompileLayer;
- LazyEmitLayerT LazyEmitLayer;
-
- std::map<std::string, std::unique_ptr<FunctionAST>> FunctionDefs;
-
- LocalJITCompileCallbackManager<OrcX86_64> CompileCallbacks;
-};
-
-static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) {
- if (auto F = ParseDefinition()) {
- S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto));
- J.addFunctionAST(std::move(F));
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleExtern(SessionContext &S) {
- if (auto P = ParseExtern())
- S.addPrototypeAST(std::move(P));
- else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
- // Evaluate a top-level expression into an anonymous function.
- if (auto F = ParseTopLevelExpr()) {
- IRGenContext C(S);
- if (auto ExprFunc = F->IRGen(C)) {
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "Expression function:\n";
- ExprFunc->dump();
-#endif
- // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove
- // this module as soon as we've executed Function ExprFunc.
- auto H = J.addModule(C.takeM());
-
- // Get the address of the JIT'd function in memory.
- auto ExprSymbol = J.findUnmangledSymbol("__anon_expr");
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
-#ifdef MINIMAL_STDERR_OUTPUT
- FP();
-#else
- std::cerr << "Evaluated to " << FP() << "\n";
-#endif
-
- // Remove the function.
- J.removeModule(H);
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-/// top ::= definition | external | expression | ';'
-static void MainLoop() {
- SessionContext S(getGlobalContext());
- KaleidoscopeJIT J(S);
-
- while (1) {
- switch (CurTok) {
- case tok_eof: return;
- case ';': getNextToken(); continue; // ignore top-level semicolons.
- case tok_def: HandleDefinition(S, J); break;
- case tok_extern: HandleExtern(S); break;
- default: HandleTopLevelExpression(S, J); break;
- }
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- }
-}
-
-//===----------------------------------------------------------------------===//
-// "Library" functions that can be "extern'd" from user code.
-//===----------------------------------------------------------------------===//
-
-/// putchard - putchar that takes a double and returns 0.
-extern "C"
-double putchard(double X) {
- putchar((char)X);
- return 0;
-}
-
-/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C"
-double printd(double X) {
- printf("%f", X);
- return 0;
-}
-
-extern "C"
-double printlf() {
- printf("\n");
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// Main driver code.
-//===----------------------------------------------------------------------===//
-
-int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
- // Install standard binary operators.
- // 1 is lowest precedence.
- BinopPrecedence['='] = 2;
- BinopPrecedence['<'] = 10;
- BinopPrecedence['+'] = 20;
- BinopPrecedence['-'] = 20;
- BinopPrecedence['/'] = 40;
- BinopPrecedence['*'] = 40; // highest.
-
- // Prime the first token.
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- getNextToken();
-
- std::cerr << std::fixed;
-
- // Run the main "interpreter loop" now.
- MainLoop();
-
- return 0;
-}
diff --git a/examples/Kaleidoscope/Orc/initial/Makefile b/examples/Kaleidoscope/Orc/initial/Makefile
deleted file mode 100644
index 5536314f2a309..0000000000000
--- a/examples/Kaleidoscope/Orc/initial/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-UNAME := $(shell uname -s)
-
-ifeq ($(UNAME),Darwin)
- CXX := xcrun --sdk macosx clang++
-else
- CXX := clang++
-endif
-
-LLVM_CXXFLAGS := $(shell llvm-config --cxxflags)
-LLVM_LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core orcjit native)
-
-toy: toy.cpp
- $(CXX) $(LLVM_CXXFLAGS) -Wall -std=c++11 -g -O0 -rdynamic -fno-rtti -o toy toy.cpp $(LLVM_LDFLAGS)
-
-.PHONY: clean
-clean:
- rm -f toy
diff --git a/examples/Kaleidoscope/Orc/initial/README.txt b/examples/Kaleidoscope/Orc/initial/README.txt
deleted file mode 100644
index 5f4cbbfe3d2c8..0000000000000
--- a/examples/Kaleidoscope/Orc/initial/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-//===----------------------------------------------------------------------===/
-// Kaleidoscope with Orc - Initial Version
-//===----------------------------------------------------------------------===//
-
-This version of Kaleidoscope with Orc demonstrates fully eager compilation. When
-a function definition or top-level expression is entered it is immediately
-translated (IRGen'd) to LLVM IR and added to the JIT, where it is code-gen'd to
-native code and either stored (for function definitions) or executed (for
-top-level expressions).
-
-This directory contain a Makefile that allow the code to be built in a
-standalone manner, independent of the larger LLVM build infrastructure. To build
-the program you will need to have 'clang++' and 'llvm-config' in your path.
diff --git a/examples/Kaleidoscope/Orc/initial/toy.cpp b/examples/Kaleidoscope/Orc/initial/toy.cpp
deleted file mode 100644
index 2a6bb92246d04..0000000000000
--- a/examples/Kaleidoscope/Orc/initial/toy.cpp
+++ /dev/null
@@ -1,1335 +0,0 @@
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
-#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
-#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Transforms/Scalar.h"
-#include <cctype>
-#include <iomanip>
-#include <iostream>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::orc;
-
-//===----------------------------------------------------------------------===//
-// Lexer
-//===----------------------------------------------------------------------===//
-
-// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
-// of these for known things.
-enum Token {
- tok_eof = -1,
-
- // commands
- tok_def = -2, tok_extern = -3,
-
- // primary
- tok_identifier = -4, tok_number = -5,
-
- // control
- tok_if = -6, tok_then = -7, tok_else = -8,
- tok_for = -9, tok_in = -10,
-
- // operators
- tok_binary = -11, tok_unary = -12,
-
- // var definition
- tok_var = -13
-};
-
-static std::string IdentifierStr; // Filled in if tok_identifier
-static double NumVal; // Filled in if tok_number
-
-/// gettok - Return the next token from standard input.
-static int gettok() {
- static int LastChar = ' ';
-
- // Skip any whitespace.
- while (isspace(LastChar))
- LastChar = getchar();
-
- if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
- IdentifierStr = LastChar;
- while (isalnum((LastChar = getchar())))
- IdentifierStr += LastChar;
-
- if (IdentifierStr == "def") return tok_def;
- if (IdentifierStr == "extern") return tok_extern;
- if (IdentifierStr == "if") return tok_if;
- if (IdentifierStr == "then") return tok_then;
- if (IdentifierStr == "else") return tok_else;
- if (IdentifierStr == "for") return tok_for;
- if (IdentifierStr == "in") return tok_in;
- if (IdentifierStr == "binary") return tok_binary;
- if (IdentifierStr == "unary") return tok_unary;
- if (IdentifierStr == "var") return tok_var;
- return tok_identifier;
- }
-
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
- std::string NumStr;
- do {
- NumStr += LastChar;
- LastChar = getchar();
- } while (isdigit(LastChar) || LastChar == '.');
-
- NumVal = strtod(NumStr.c_str(), nullptr);
- return tok_number;
- }
-
- if (LastChar == '#') {
- // Comment until end of line.
- do LastChar = getchar();
- while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
-
- if (LastChar != EOF)
- return gettok();
- }
-
- // Check for end of file. Don't eat the EOF.
- if (LastChar == EOF)
- return tok_eof;
-
- // Otherwise, just return the character as its ascii value.
- int ThisChar = LastChar;
- LastChar = getchar();
- return ThisChar;
-}
-
-//===----------------------------------------------------------------------===//
-// Abstract Syntax Tree (aka Parse Tree)
-//===----------------------------------------------------------------------===//
-
-class IRGenContext;
-
-/// ExprAST - Base class for all expression nodes.
-struct ExprAST {
- virtual ~ExprAST() {}
- virtual Value *IRGen(IRGenContext &C) const = 0;
-};
-
-/// NumberExprAST - Expression class for numeric literals like "1.0".
-struct NumberExprAST : public ExprAST {
- NumberExprAST(double Val) : Val(Val) {}
- Value *IRGen(IRGenContext &C) const override;
-
- double Val;
-};
-
-/// VariableExprAST - Expression class for referencing a variable, like "a".
-struct VariableExprAST : public ExprAST {
- VariableExprAST(std::string Name) : Name(std::move(Name)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::string Name;
-};
-
-/// UnaryExprAST - Expression class for a unary operator.
-struct UnaryExprAST : public ExprAST {
- UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
- : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Opcode;
- std::unique_ptr<ExprAST> Operand;
-};
-
-/// BinaryExprAST - Expression class for a binary operator.
-struct BinaryExprAST : public ExprAST {
- BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
- std::unique_ptr<ExprAST> RHS)
- : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Op;
- std::unique_ptr<ExprAST> LHS, RHS;
-};
-
-/// CallExprAST - Expression class for function calls.
-struct CallExprAST : public ExprAST {
- CallExprAST(std::string CalleeName,
- std::vector<std::unique_ptr<ExprAST>> Args)
- : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string CalleeName;
- std::vector<std::unique_ptr<ExprAST>> Args;
-};
-
-/// IfExprAST - Expression class for if/then/else.
-struct IfExprAST : public ExprAST {
- IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
- std::unique_ptr<ExprAST> Else)
- : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::unique_ptr<ExprAST> Cond, Then, Else;
-};
-
-/// ForExprAST - Expression class for for/in.
-struct ForExprAST : public ExprAST {
- ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start,
- std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
- std::unique_ptr<ExprAST> Body)
- : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)),
- Step(std::move(Step)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string VarName;
- std::unique_ptr<ExprAST> Start, End, Step, Body;
-};
-
-/// VarExprAST - Expression class for var/in
-struct VarExprAST : public ExprAST {
- typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding;
- typedef std::vector<Binding> BindingList;
-
- VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body)
- : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- BindingList VarBindings;
- std::unique_ptr<ExprAST> Body;
-};
-
-/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
-struct PrototypeAST {
- PrototypeAST(std::string Name, std::vector<std::string> Args,
- bool IsOperator = false, unsigned Precedence = 0)
- : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Precedence) {}
-
- Function *IRGen(IRGenContext &C) const;
- void CreateArgumentAllocas(Function *F, IRGenContext &C);
-
- bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
- bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
-
- char getOperatorName() const {
- assert(isUnaryOp() || isBinaryOp());
- return Name[Name.size()-1];
- }
-
- std::string Name;
- std::vector<std::string> Args;
- bool IsOperator;
- unsigned Precedence; // Precedence if a binary op.
-};
-
-/// FunctionAST - This class represents a function definition itself.
-struct FunctionAST {
- FunctionAST(std::unique_ptr<PrototypeAST> Proto,
- std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
-
- Function *IRGen(IRGenContext &C) const;
-
- std::unique_ptr<PrototypeAST> Proto;
- std::unique_ptr<ExprAST> Body;
-};
-
-//===----------------------------------------------------------------------===//
-// Parser
-//===----------------------------------------------------------------------===//
-
-/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
-/// token the parser is looking at. getNextToken reads another token from the
-/// lexer and updates CurTok with its results.
-static int CurTok;
-static int getNextToken() {
- return CurTok = gettok();
-}
-
-/// BinopPrecedence - This holds the precedence for each binary operator that is
-/// defined.
-static std::map<char, int> BinopPrecedence;
-
-/// GetTokPrecedence - Get the precedence of the pending binary operator token.
-static int GetTokPrecedence() {
- if (!isascii(CurTok))
- return -1;
-
- // Make sure it's a declared binop.
- int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
- return TokPrec;
-}
-
-template <typename T>
-std::unique_ptr<T> ErrorU(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-template <typename T>
-T* ErrorP(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-static std::unique_ptr<ExprAST> ParseExpression();
-
-/// identifierexpr
-/// ::= identifier
-/// ::= identifier '(' expression* ')'
-static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
- std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
- if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(IdName);
-
- // Call.
- getNextToken(); // eat (
- std::vector<std::unique_ptr<ExprAST>> Args;
- if (CurTok != ')') {
- while (1) {
- auto Arg = ParseExpression();
- if (!Arg) return nullptr;
- Args.push_back(std::move(Arg));
-
- if (CurTok == ')') break;
-
- if (CurTok != ',')
- return ErrorU<CallExprAST>("Expected ')' or ',' in argument list");
- getNextToken();
- }
- }
-
- // Eat the ')'.
- getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-
-/// numberexpr ::= number
-static std::unique_ptr<NumberExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return Result;
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return ErrorU<ExprAST>("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
-/// ifexpr ::= 'if' expression 'then' expression 'else' expression
-static std::unique_ptr<ExprAST> ParseIfExpr() {
- getNextToken(); // eat the if.
-
- // condition.
- auto Cond = ParseExpression();
- if (!Cond)
- return nullptr;
-
- if (CurTok != tok_then)
- return ErrorU<ExprAST>("expected then");
- getNextToken(); // eat the then
-
- auto Then = ParseExpression();
- if (!Then)
- return nullptr;
-
- if (CurTok != tok_else)
- return ErrorU<ExprAST>("expected else");
-
- getNextToken();
-
- auto Else = ParseExpression();
- if (!Else)
- return nullptr;
-
- return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
- std::move(Else));
-}
-
-/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
-static std::unique_ptr<ForExprAST> ParseForExpr() {
- getNextToken(); // eat the for.
-
- if (CurTok != tok_identifier)
- return ErrorU<ForExprAST>("expected identifier after for");
-
- std::string IdName = IdentifierStr;
- getNextToken(); // eat identifier.
-
- if (CurTok != '=')
- return ErrorU<ForExprAST>("expected '=' after for");
- getNextToken(); // eat '='.
-
- auto Start = ParseExpression();
- if (!Start)
- return nullptr;
- if (CurTok != ',')
- return ErrorU<ForExprAST>("expected ',' after for start value");
- getNextToken();
-
- auto End = ParseExpression();
- if (!End)
- return nullptr;
-
- // The step value is optional.
- std::unique_ptr<ExprAST> Step;
- if (CurTok == ',') {
- getNextToken();
- Step = ParseExpression();
- if (!Step)
- return nullptr;
- }
-
- if (CurTok != tok_in)
- return ErrorU<ForExprAST>("expected 'in' after for");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (Body)
- return nullptr;
-
- return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
- std::move(Step), std::move(Body));
-}
-
-/// varexpr ::= 'var' identifier ('=' expression)?
-// (',' identifier ('=' expression)?)* 'in' expression
-static std::unique_ptr<VarExprAST> ParseVarExpr() {
- getNextToken(); // eat the var.
-
- VarExprAST::BindingList VarBindings;
-
- // At least one variable name is required.
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier after var");
-
- while (1) {
- std::string Name = IdentifierStr;
- getNextToken(); // eat identifier.
-
- // Read the optional initializer.
- std::unique_ptr<ExprAST> Init;
- if (CurTok == '=') {
- getNextToken(); // eat the '='.
-
- Init = ParseExpression();
- if (!Init)
- return nullptr;
- }
-
- VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init)));
-
- // End of var list, exit loop.
- if (CurTok != ',') break;
- getNextToken(); // eat the ','.
-
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier list after var");
- }
-
- // At this point, we have to have 'in'.
- if (CurTok != tok_in)
- return ErrorU<VarExprAST>("expected 'in' keyword after 'var'");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (!Body)
- return nullptr;
-
- return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body));
-}
-
-/// primary
-/// ::= identifierexpr
-/// ::= numberexpr
-/// ::= parenexpr
-/// ::= ifexpr
-/// ::= forexpr
-/// ::= varexpr
-static std::unique_ptr<ExprAST> ParsePrimary() {
- switch (CurTok) {
- default: return ErrorU<ExprAST>("unknown token when expecting an expression");
- case tok_identifier: return ParseIdentifierExpr();
- case tok_number: return ParseNumberExpr();
- case '(': return ParseParenExpr();
- case tok_if: return ParseIfExpr();
- case tok_for: return ParseForExpr();
- case tok_var: return ParseVarExpr();
- }
-}
-
-/// unary
-/// ::= primary
-/// ::= '!' unary
-static std::unique_ptr<ExprAST> ParseUnary() {
- // If the current token is not an operator, it must be a primary expr.
- if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
- return ParsePrimary();
-
- // If this is a unary operator, read it.
- int Opc = CurTok;
- getNextToken();
- if (auto Operand = ParseUnary())
- return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
- return nullptr;
-}
-
-/// binoprhs
-/// ::= ('+' unary)*
-static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
- std::unique_ptr<ExprAST> LHS) {
- // If this is a binop, find its precedence.
- while (1) {
- int TokPrec = GetTokPrecedence();
-
- // If this is a binop that binds at least as tightly as the current binop,
- // consume it, otherwise we are done.
- if (TokPrec < ExprPrec)
- return LHS;
-
- // Okay, we know this is a binop.
- int BinOp = CurTok;
- getNextToken(); // eat binop
-
- // Parse the unary expression after the binary operator.
- auto RHS = ParseUnary();
- if (!RHS)
- return nullptr;
-
- // If BinOp binds less tightly with RHS than the operator after RHS, let
- // the pending operator take RHS as its LHS.
- int NextPrec = GetTokPrecedence();
- if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
- if (!RHS)
- return nullptr;
- }
-
- // Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
- }
-}
-
-/// expression
-/// ::= unary binoprhs
-///
-static std::unique_ptr<ExprAST> ParseExpression() {
- auto LHS = ParseUnary();
- if (!LHS)
- return nullptr;
-
- return ParseBinOpRHS(0, std::move(LHS));
-}
-
-/// prototype
-/// ::= id '(' id* ')'
-/// ::= binary LETTER number? (id, id)
-/// ::= unary LETTER (id)
-static std::unique_ptr<PrototypeAST> ParsePrototype() {
- std::string FnName;
-
- unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
- unsigned BinaryPrecedence = 30;
-
- switch (CurTok) {
- default:
- return ErrorU<PrototypeAST>("Expected function name in prototype");
- case tok_identifier:
- FnName = IdentifierStr;
- Kind = 0;
- getNextToken();
- break;
- case tok_unary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected unary operator");
- FnName = "unary";
- FnName += (char)CurTok;
- Kind = 1;
- getNextToken();
- break;
- case tok_binary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected binary operator");
- FnName = "binary";
- FnName += (char)CurTok;
- Kind = 2;
- getNextToken();
-
- // Read the precedence if present.
- if (CurTok == tok_number) {
- if (NumVal < 1 || NumVal > 100)
- return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100");
- BinaryPrecedence = (unsigned)NumVal;
- getNextToken();
- }
- break;
- }
-
- if (CurTok != '(')
- return ErrorU<PrototypeAST>("Expected '(' in prototype");
-
- std::vector<std::string> ArgNames;
- while (getNextToken() == tok_identifier)
- ArgNames.push_back(IdentifierStr);
- if (CurTok != ')')
- return ErrorU<PrototypeAST>("Expected ')' in prototype");
-
- // success.
- getNextToken(); // eat ')'.
-
- // Verify right number of names for operator.
- if (Kind && ArgNames.size() != Kind)
- return ErrorU<PrototypeAST>("Invalid number of operands for operator");
-
- return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
- BinaryPrecedence);
-}
-
-/// definition ::= 'def' prototype expression
-static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
- auto Proto = ParsePrototype();
- if (!Proto)
- return nullptr;
-
- if (auto Body = ParseExpression())
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body));
- return nullptr;
-}
-
-/// toplevelexpr ::= expression
-static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- if (auto E = ParseExpression()) {
- // Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
- }
- return nullptr;
-}
-
-/// external ::= 'extern' prototype
-static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
- return ParsePrototype();
-}
-
-//===----------------------------------------------------------------------===//
-// Code Generation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Obviously we can do better than this
-std::string GenerateUniqueName(const std::string &Root) {
- static int i = 0;
- std::ostringstream NameStream;
- NameStream << Root << ++i;
- return NameStream.str();
-}
-
-std::string MakeLegalFunctionName(std::string Name)
-{
- std::string NewName;
- assert(!Name.empty() && "Base name must not be empty");
-
- // Start with what we have
- NewName = Name;
-
- // Look for a numberic first character
- if (NewName.find_first_of("0123456789") == 0) {
- NewName.insert(0, 1, 'n');
- }
-
- // Replace illegal characters with their ASCII equivalent
- std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- size_t pos;
- while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {
- std::ostringstream NumStream;
- NumStream << (int)NewName.at(pos);
- NewName = NewName.replace(pos, 1, NumStream.str());
- }
-
- return NewName;
-}
-
-class SessionContext {
-public:
- SessionContext(LLVMContext &C)
- : Context(C), TM(EngineBuilder().selectTarget()) {}
- LLVMContext& getLLVMContext() const { return Context; }
- TargetMachine& getTarget() { return *TM; }
- void addPrototypeAST(std::unique_ptr<PrototypeAST> P);
- PrototypeAST* getPrototypeAST(const std::string &Name);
-private:
- typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap;
-
- LLVMContext &Context;
- std::unique_ptr<TargetMachine> TM;
-
- PrototypeMap Prototypes;
-};
-
-void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) {
- Prototypes[P->Name] = std::move(P);
-}
-
-PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) {
- PrototypeMap::iterator I = Prototypes.find(Name);
- if (I != Prototypes.end())
- return I->second.get();
- return nullptr;
-}
-
-class IRGenContext {
-public:
-
- IRGenContext(SessionContext &S)
- : Session(S),
- M(new Module(GenerateUniqueName("jit_module_"),
- Session.getLLVMContext())),
- Builder(Session.getLLVMContext()) {
- M->setDataLayout(Session.getTarget().createDataLayout());
- }
-
- SessionContext& getSession() { return Session; }
- Module& getM() const { return *M; }
- std::unique_ptr<Module> takeM() { return std::move(M); }
- IRBuilder<>& getBuilder() { return Builder; }
- LLVMContext& getLLVMContext() { return Session.getLLVMContext(); }
- Function* getPrototype(const std::string &Name);
-
- std::map<std::string, AllocaInst*> NamedValues;
-private:
- SessionContext &Session;
- std::unique_ptr<Module> M;
- IRBuilder<> Builder;
-};
-
-Function* IRGenContext::getPrototype(const std::string &Name) {
- if (Function *ExistingProto = M->getFunction(Name))
- return ExistingProto;
- if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name))
- return ProtoAST->IRGen(*this);
- return nullptr;
-}
-
-/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
-/// the function. This is used for mutable variables etc.
-static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
- const std::string &VarName) {
- IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
- TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
-}
-
-Value *NumberExprAST::IRGen(IRGenContext &C) const {
- return ConstantFP::get(C.getLLVMContext(), APFloat(Val));
-}
-
-Value *VariableExprAST::IRGen(IRGenContext &C) const {
- // Look this variable up in the function.
- Value *V = C.NamedValues[Name];
-
- if (!V)
- return ErrorP<Value>("Unknown variable name '" + Name + "'");
-
- // Load the value.
- return C.getBuilder().CreateLoad(V, Name.c_str());
-}
-
-Value *UnaryExprAST::IRGen(IRGenContext &C) const {
- if (Value *OperandV = Operand->IRGen(C)) {
- std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode);
- if (Function *F = C.getPrototype(FnName))
- return C.getBuilder().CreateCall(F, OperandV, "unop");
- return ErrorP<Value>("Unknown unary operator");
- }
-
- // Could not codegen operand - return null.
- return nullptr;
-}
-
-Value *BinaryExprAST::IRGen(IRGenContext &C) const {
- // Special case '=' because we don't want to emit the LHS as an expression.
- if (Op == '=') {
- // Assignment requires the LHS to be an identifier.
- auto &LHSVar = static_cast<VariableExprAST &>(*LHS);
- // Codegen the RHS.
- Value *Val = RHS->IRGen(C);
- if (!Val) return nullptr;
-
- // Look up the name.
- if (auto Variable = C.NamedValues[LHSVar.Name]) {
- C.getBuilder().CreateStore(Val, Variable);
- return Val;
- }
- return ErrorP<Value>("Unknown variable name");
- }
-
- Value *L = LHS->IRGen(C);
- Value *R = RHS->IRGen(C);
- if (!L || !R) return nullptr;
-
- switch (Op) {
- case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp");
- case '-': return C.getBuilder().CreateFSub(L, R, "subtmp");
- case '*': return C.getBuilder().CreateFMul(L, R, "multmp");
- case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp");
- case '<':
- L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp");
- // Convert bool 0/1 to double 0.0 or 1.0
- return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
- default: break;
- }
-
- // If it wasn't a builtin binary operator, it must be a user defined one. Emit
- // a call to it.
- std::string FnName = MakeLegalFunctionName(std::string("binary")+Op);
- if (Function *F = C.getPrototype(FnName)) {
- Value *Ops[] = { L, R };
- return C.getBuilder().CreateCall(F, Ops, "binop");
- }
-
- return ErrorP<Value>("Unknown binary operator");
-}
-
-Value *CallExprAST::IRGen(IRGenContext &C) const {
- // Look up the name in the global module table.
- if (auto CalleeF = C.getPrototype(CalleeName)) {
- // If argument mismatch error.
- if (CalleeF->arg_size() != Args.size())
- return ErrorP<Value>("Incorrect # arguments passed");
-
- std::vector<Value*> ArgsV;
- for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- ArgsV.push_back(Args[i]->IRGen(C));
- if (!ArgsV.back()) return nullptr;
- }
-
- return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp");
- }
-
- return ErrorP<Value>("Unknown function referenced");
-}
-
-Value *IfExprAST::IRGen(IRGenContext &C) const {
- Value *CondV = Cond->IRGen(C);
- if (!CondV) return nullptr;
-
- // Convert condition to a bool by comparing equal to 0.0.
- ConstantFP *FPZero =
- ConstantFP::get(C.getLLVMContext(), APFloat(0.0));
- CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond");
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create blocks for the then and else cases. Insert the 'then' block at the
- // end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont");
-
- C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB);
-
- // Emit then value.
- C.getBuilder().SetInsertPoint(ThenBB);
-
- Value *ThenV = Then->IRGen(C);
- if (!ThenV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
- ThenBB = C.getBuilder().GetInsertBlock();
-
- // Emit else block.
- TheFunction->getBasicBlockList().push_back(ElseBB);
- C.getBuilder().SetInsertPoint(ElseBB);
-
- Value *ElseV = Else->IRGen(C);
- if (!ElseV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
- ElseBB = C.getBuilder().GetInsertBlock();
-
- // Emit merge block.
- TheFunction->getBasicBlockList().push_back(MergeBB);
- C.getBuilder().SetInsertPoint(MergeBB);
- PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
- PN->addIncoming(ThenV, ThenBB);
- PN->addIncoming(ElseV, ElseBB);
- return PN;
-}
-
-Value *ForExprAST::IRGen(IRGenContext &C) const {
- // Output this as:
- // var = alloca double
- // ...
- // start = startexpr
- // store start -> var
- // goto loop
- // loop:
- // ...
- // bodyexpr
- // ...
- // loopend:
- // step = stepexpr
- // endcond = endexpr
- //
- // curvar = load var
- // nextvar = curvar + step
- // store nextvar -> var
- // br endcond, loop, endloop
- // outloop:
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create an alloca for the variable in the entry block.
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
-
- // Emit the start code first, without 'variable' in scope.
- Value *StartVal = Start->IRGen(C);
- if (!StartVal) return nullptr;
-
- // Store the value into the alloca.
- C.getBuilder().CreateStore(StartVal, Alloca);
-
- // Make the new basic block for the loop header, inserting after current
- // block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
- // Insert an explicit fall through from the current block to the LoopBB.
- C.getBuilder().CreateBr(LoopBB);
-
- // Start insertion in LoopBB.
- C.getBuilder().SetInsertPoint(LoopBB);
-
- // Within the loop, the variable is defined equal to the PHI node. If it
- // shadows an existing variable, we have to restore it, so save it now.
- AllocaInst *OldVal = C.NamedValues[VarName];
- C.NamedValues[VarName] = Alloca;
-
- // Emit the body of the loop. This, like any other expr, can change the
- // current BB. Note that we ignore the value computed by the body, but don't
- // allow an error.
- if (!Body->IRGen(C))
- return nullptr;
-
- // Emit the step value.
- Value *StepVal;
- if (Step) {
- StepVal = Step->IRGen(C);
- if (!StepVal) return nullptr;
- } else {
- // If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
- }
-
- // Compute the end condition.
- Value *EndCond = End->IRGen(C);
- if (!EndCond) return nullptr;
-
- // Reload, increment, and restore the alloca. This handles the case where
- // the body of the loop mutates the variable.
- Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str());
- Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar");
- C.getBuilder().CreateStore(NextVar, Alloca);
-
- // Convert condition to a bool by comparing equal to 0.0.
- EndCond = C.getBuilder().CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
- // Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
- // Insert the conditional branch into the end of LoopEndBB.
- C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB);
-
- // Any new code will be inserted in AfterBB.
- C.getBuilder().SetInsertPoint(AfterBB);
-
- // Restore the unshadowed variable.
- if (OldVal)
- C.NamedValues[VarName] = OldVal;
- else
- C.NamedValues.erase(VarName);
-
- // for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
-}
-
-Value *VarExprAST::IRGen(IRGenContext &C) const {
- std::vector<AllocaInst *> OldBindings;
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Register all variables and emit their initializer.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) {
- auto &VarName = VarBindings[i].first;
- auto &Init = VarBindings[i].second;
-
- // Emit the initializer before adding the variable to scope, this prevents
- // the initializer from referencing the variable itself, and permits stuff
- // like this:
- // var a = 1 in
- // var a = a in ... # refers to outer 'a'.
- Value *InitVal;
- if (Init) {
- InitVal = Init->IRGen(C);
- if (!InitVal) return nullptr;
- } else // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
-
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- C.getBuilder().CreateStore(InitVal, Alloca);
-
- // Remember the old variable binding so that we can restore the binding when
- // we unrecurse.
- OldBindings.push_back(C.NamedValues[VarName]);
-
- // Remember this binding.
- C.NamedValues[VarName] = Alloca;
- }
-
- // Codegen the body, now that all vars are in scope.
- Value *BodyVal = Body->IRGen(C);
- if (!BodyVal) return nullptr;
-
- // Pop all our variables from scope.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i)
- C.NamedValues[VarBindings[i].first] = OldBindings[i];
-
- // Return the body computation.
- return BodyVal;
-}
-
-Function *PrototypeAST::IRGen(IRGenContext &C) const {
- std::string FnName = MakeLegalFunctionName(Name);
-
- // Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
- Function *F = Function::Create(FT, Function::ExternalLinkage, FnName,
- &C.getM());
-
- // If F conflicted, there was already something named 'FnName'. If it has a
- // body, don't allow redefinition or reextern.
- if (F->getName() != FnName) {
- // Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = C.getM().getFunction(Name);
-
- // If F already has a body, reject this.
- if (!F->empty()) {
- ErrorP<Function>("redefinition of function");
- return nullptr;
- }
-
- // If F took a different number of args, reject.
- if (F->arg_size() != Args.size()) {
- ErrorP<Function>("redefinition of function with different # args");
- return nullptr;
- }
- }
-
- // Set names for all arguments.
- unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
- ++AI, ++Idx)
- AI->setName(Args[Idx]);
-
- return F;
-}
-
-/// CreateArgumentAllocas - Create an alloca for each argument and register the
-/// argument in the symbol table so that references to it will succeed.
-void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) {
- Function::arg_iterator AI = F->arg_begin();
- for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
- // Create an alloca for this variable.
- AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
-
- // Store the initial value into the alloca.
- C.getBuilder().CreateStore(&*AI, Alloca);
-
- // Add arguments to variable symbol table.
- C.NamedValues[Args[Idx]] = Alloca;
- }
-}
-
-Function *FunctionAST::IRGen(IRGenContext &C) const {
- C.NamedValues.clear();
-
- Function *TheFunction = Proto->IRGen(C);
- if (!TheFunction)
- return nullptr;
-
- // If this is an operator, install it.
- if (Proto->isBinaryOp())
- BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence;
-
- // Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
- C.getBuilder().SetInsertPoint(BB);
-
- // Add all arguments to the symbol table and create their allocas.
- Proto->CreateArgumentAllocas(TheFunction, C);
-
- if (Value *RetVal = Body->IRGen(C)) {
- // Finish off the function.
- C.getBuilder().CreateRet(RetVal);
-
- // Validate the generated code, checking for consistency.
- verifyFunction(*TheFunction);
-
- return TheFunction;
- }
-
- // Error reading body, remove function.
- TheFunction->eraseFromParent();
-
- if (Proto->isBinaryOp())
- BinopPrecedence.erase(Proto->getOperatorName());
- return nullptr;
-}
-
-//===----------------------------------------------------------------------===//
-// Top-Level parsing and JIT Driver
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<llvm::Module> IRGen(SessionContext &S,
- const FunctionAST &F) {
- IRGenContext C(S);
- auto LF = F.IRGen(C);
- if (!LF)
- return nullptr;
-#ifndef MINIMAL_STDERR_OUTPUT
- fprintf(stderr, "Read function definition:");
- LF->dump();
-#endif
- return C.takeM();
-}
-
-template <typename T>
-static std::vector<T> singletonSet(T t) {
- std::vector<T> Vec;
- Vec.push_back(std::move(t));
- return Vec;
-}
-
-class KaleidoscopeJIT {
-public:
- typedef ObjectLinkingLayer<> ObjLayerT;
- typedef IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
-
- KaleidoscopeJIT(SessionContext &Session)
- : DL(Session.getTarget().createDataLayout()),
- CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())) {}
-
- std::string mangle(const std::string &Name) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
- }
- return MangledName;
- }
-
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- // We need a memory manager to allocate memory and resolve symbols for this
- // new module. Create one that resolves symbols by looking back into the
- // JIT.
- auto Resolver = createLambdaResolver(
- [&](const std::string &Name) {
- if (auto Sym = findSymbol(Name))
- return RuntimeDyld::SymbolInfo(Sym.getAddress(),
- Sym.getFlags());
- return RuntimeDyld::SymbolInfo(nullptr);
- },
- [](const std::string &S) { return nullptr; }
- );
- return CompileLayer.addModuleSet(singletonSet(std::move(M)),
- make_unique<SectionMemoryManager>(),
- std::move(Resolver));
- }
-
- void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); }
-
- JITSymbol findSymbol(const std::string &Name) {
- return CompileLayer.findSymbol(Name, true);
- }
-
- JITSymbol findUnmangledSymbol(const std::string Name) {
- return findSymbol(mangle(Name));
- }
-
-private:
- const DataLayout DL;
- ObjLayerT ObjectLayer;
- CompileLayerT CompileLayer;
-};
-
-static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) {
- if (auto F = ParseDefinition()) {
- if (auto M = IRGen(S, *F)) {
- S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto));
- J.addModule(std::move(M));
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleExtern(SessionContext &S) {
- if (auto P = ParseExtern())
- S.addPrototypeAST(std::move(P));
- else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
- // Evaluate a top-level expression into an anonymous function.
- if (auto F = ParseTopLevelExpr()) {
- IRGenContext C(S);
- if (auto ExprFunc = F->IRGen(C)) {
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "Expression function:\n";
- ExprFunc->dump();
-#endif
- // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove
- // this module as soon as we've executed Function ExprFunc.
- auto H = J.addModule(C.takeM());
-
- // Get the address of the JIT'd function in memory.
- auto ExprSymbol = J.findUnmangledSymbol("__anon_expr");
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
-#ifdef MINIMAL_STDERR_OUTPUT
- FP();
-#else
- std::cerr << "Evaluated to " << FP() << "\n";
-#endif
-
- // Remove the function.
- J.removeModule(H);
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-/// top ::= definition | external | expression | ';'
-static void MainLoop() {
- SessionContext S(getGlobalContext());
- KaleidoscopeJIT J(S);
-
- while (1) {
- switch (CurTok) {
- case tok_eof: return;
- case ';': getNextToken(); continue; // ignore top-level semicolons.
- case tok_def: HandleDefinition(S, J); break;
- case tok_extern: HandleExtern(S); break;
- default: HandleTopLevelExpression(S, J); break;
- }
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- }
-}
-
-//===----------------------------------------------------------------------===//
-// "Library" functions that can be "extern'd" from user code.
-//===----------------------------------------------------------------------===//
-
-/// putchard - putchar that takes a double and returns 0.
-extern "C"
-double putchard(double X) {
- putchar((char)X);
- return 0;
-}
-
-/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C"
-double printd(double X) {
- printf("%f", X);
- return 0;
-}
-
-extern "C"
-double printlf() {
- printf("\n");
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// Main driver code.
-//===----------------------------------------------------------------------===//
-
-int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
- // Install standard binary operators.
- // 1 is lowest precedence.
- BinopPrecedence['='] = 2;
- BinopPrecedence['<'] = 10;
- BinopPrecedence['+'] = 20;
- BinopPrecedence['-'] = 20;
- BinopPrecedence['/'] = 40;
- BinopPrecedence['*'] = 40; // highest.
-
- // Prime the first token.
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- getNextToken();
-
- std::cerr << std::fixed;
-
- // Run the main "interpreter loop" now.
- MainLoop();
-
- return 0;
-}
diff --git a/examples/Kaleidoscope/Orc/lazy_codegen/CMakeLists.txt b/examples/Kaleidoscope/Orc/lazy_codegen/CMakeLists.txt
deleted file mode 100644
index faad3420c6a02..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_codegen/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- Core
- ExecutionEngine
- Object
- RuntimeDyld
- Support
- native
- )
-
-add_kaleidoscope_chapter(Kaleidoscope-Orc-lazy_codegen
- toy.cpp
- )
diff --git a/examples/Kaleidoscope/Orc/lazy_codegen/Makefile b/examples/Kaleidoscope/Orc/lazy_codegen/Makefile
deleted file mode 100644
index 5536314f2a309..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_codegen/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-UNAME := $(shell uname -s)
-
-ifeq ($(UNAME),Darwin)
- CXX := xcrun --sdk macosx clang++
-else
- CXX := clang++
-endif
-
-LLVM_CXXFLAGS := $(shell llvm-config --cxxflags)
-LLVM_LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core orcjit native)
-
-toy: toy.cpp
- $(CXX) $(LLVM_CXXFLAGS) -Wall -std=c++11 -g -O0 -rdynamic -fno-rtti -o toy toy.cpp $(LLVM_LDFLAGS)
-
-.PHONY: clean
-clean:
- rm -f toy
diff --git a/examples/Kaleidoscope/Orc/lazy_codegen/README.txt b/examples/Kaleidoscope/Orc/lazy_codegen/README.txt
deleted file mode 100644
index 9d62a91432797..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_codegen/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-//===----------------------------------------------------------------------===/
-// Kaleidoscope with Orc - Initial Version
-//===----------------------------------------------------------------------===//
-
-This version of Kaleidoscope with Orc demonstrates lazy code-generation.
-Unlike the first Kaleidoscope-Orc tutorial, where code-gen was performed as soon
-as modules were added to the JIT, this tutorial adds a LazyEmittingLayer to defer
-code-generation until modules are actually referenced. All IR-generation is still
-performed up-front.
-
-This directory contain a Makefile that allow the code to be built in a
-standalone manner, independent of the larger LLVM build infrastructure. To build
-the program you will need to have 'clang++' and 'llvm-config' in your path.
diff --git a/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp b/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp
deleted file mode 100644
index 5205b406ed718..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp
+++ /dev/null
@@ -1,1339 +0,0 @@
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
-#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
-#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Transforms/Scalar.h"
-#include <cctype>
-#include <iomanip>
-#include <iostream>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::orc;
-
-//===----------------------------------------------------------------------===//
-// Lexer
-//===----------------------------------------------------------------------===//
-
-// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
-// of these for known things.
-enum Token {
- tok_eof = -1,
-
- // commands
- tok_def = -2, tok_extern = -3,
-
- // primary
- tok_identifier = -4, tok_number = -5,
-
- // control
- tok_if = -6, tok_then = -7, tok_else = -8,
- tok_for = -9, tok_in = -10,
-
- // operators
- tok_binary = -11, tok_unary = -12,
-
- // var definition
- tok_var = -13
-};
-
-static std::string IdentifierStr; // Filled in if tok_identifier
-static double NumVal; // Filled in if tok_number
-
-/// gettok - Return the next token from standard input.
-static int gettok() {
- static int LastChar = ' ';
-
- // Skip any whitespace.
- while (isspace(LastChar))
- LastChar = getchar();
-
- if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
- IdentifierStr = LastChar;
- while (isalnum((LastChar = getchar())))
- IdentifierStr += LastChar;
-
- if (IdentifierStr == "def") return tok_def;
- if (IdentifierStr == "extern") return tok_extern;
- if (IdentifierStr == "if") return tok_if;
- if (IdentifierStr == "then") return tok_then;
- if (IdentifierStr == "else") return tok_else;
- if (IdentifierStr == "for") return tok_for;
- if (IdentifierStr == "in") return tok_in;
- if (IdentifierStr == "binary") return tok_binary;
- if (IdentifierStr == "unary") return tok_unary;
- if (IdentifierStr == "var") return tok_var;
- return tok_identifier;
- }
-
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
- std::string NumStr;
- do {
- NumStr += LastChar;
- LastChar = getchar();
- } while (isdigit(LastChar) || LastChar == '.');
-
- NumVal = strtod(NumStr.c_str(), nullptr);
- return tok_number;
- }
-
- if (LastChar == '#') {
- // Comment until end of line.
- do LastChar = getchar();
- while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
-
- if (LastChar != EOF)
- return gettok();
- }
-
- // Check for end of file. Don't eat the EOF.
- if (LastChar == EOF)
- return tok_eof;
-
- // Otherwise, just return the character as its ascii value.
- int ThisChar = LastChar;
- LastChar = getchar();
- return ThisChar;
-}
-
-//===----------------------------------------------------------------------===//
-// Abstract Syntax Tree (aka Parse Tree)
-//===----------------------------------------------------------------------===//
-
-class IRGenContext;
-
-/// ExprAST - Base class for all expression nodes.
-struct ExprAST {
- virtual ~ExprAST() {}
- virtual Value *IRGen(IRGenContext &C) const = 0;
-};
-
-/// NumberExprAST - Expression class for numeric literals like "1.0".
-struct NumberExprAST : public ExprAST {
- NumberExprAST(double Val) : Val(Val) {}
- Value *IRGen(IRGenContext &C) const override;
-
- double Val;
-};
-
-/// VariableExprAST - Expression class for referencing a variable, like "a".
-struct VariableExprAST : public ExprAST {
- VariableExprAST(std::string Name) : Name(std::move(Name)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::string Name;
-};
-
-/// UnaryExprAST - Expression class for a unary operator.
-struct UnaryExprAST : public ExprAST {
- UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
- : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Opcode;
- std::unique_ptr<ExprAST> Operand;
-};
-
-/// BinaryExprAST - Expression class for a binary operator.
-struct BinaryExprAST : public ExprAST {
- BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
- std::unique_ptr<ExprAST> RHS)
- : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Op;
- std::unique_ptr<ExprAST> LHS, RHS;
-};
-
-/// CallExprAST - Expression class for function calls.
-struct CallExprAST : public ExprAST {
- CallExprAST(std::string CalleeName,
- std::vector<std::unique_ptr<ExprAST>> Args)
- : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string CalleeName;
- std::vector<std::unique_ptr<ExprAST>> Args;
-};
-
-/// IfExprAST - Expression class for if/then/else.
-struct IfExprAST : public ExprAST {
- IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
- std::unique_ptr<ExprAST> Else)
- : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::unique_ptr<ExprAST> Cond, Then, Else;
-};
-
-/// ForExprAST - Expression class for for/in.
-struct ForExprAST : public ExprAST {
- ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start,
- std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
- std::unique_ptr<ExprAST> Body)
- : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)),
- Step(std::move(Step)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string VarName;
- std::unique_ptr<ExprAST> Start, End, Step, Body;
-};
-
-/// VarExprAST - Expression class for var/in
-struct VarExprAST : public ExprAST {
- typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding;
- typedef std::vector<Binding> BindingList;
-
- VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body)
- : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- BindingList VarBindings;
- std::unique_ptr<ExprAST> Body;
-};
-
-/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
-struct PrototypeAST {
- PrototypeAST(std::string Name, std::vector<std::string> Args,
- bool IsOperator = false, unsigned Precedence = 0)
- : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Precedence) {}
-
- Function *IRGen(IRGenContext &C) const;
- void CreateArgumentAllocas(Function *F, IRGenContext &C);
-
- bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
- bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
-
- char getOperatorName() const {
- assert(isUnaryOp() || isBinaryOp());
- return Name[Name.size()-1];
- }
-
- std::string Name;
- std::vector<std::string> Args;
- bool IsOperator;
- unsigned Precedence; // Precedence if a binary op.
-};
-
-/// FunctionAST - This class represents a function definition itself.
-struct FunctionAST {
- FunctionAST(std::unique_ptr<PrototypeAST> Proto,
- std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
-
- Function *IRGen(IRGenContext &C) const;
-
- std::unique_ptr<PrototypeAST> Proto;
- std::unique_ptr<ExprAST> Body;
-};
-
-//===----------------------------------------------------------------------===//
-// Parser
-//===----------------------------------------------------------------------===//
-
-/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
-/// token the parser is looking at. getNextToken reads another token from the
-/// lexer and updates CurTok with its results.
-static int CurTok;
-static int getNextToken() {
- return CurTok = gettok();
-}
-
-/// BinopPrecedence - This holds the precedence for each binary operator that is
-/// defined.
-static std::map<char, int> BinopPrecedence;
-
-/// GetTokPrecedence - Get the precedence of the pending binary operator token.
-static int GetTokPrecedence() {
- if (!isascii(CurTok))
- return -1;
-
- // Make sure it's a declared binop.
- int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
- return TokPrec;
-}
-
-template <typename T>
-std::unique_ptr<T> ErrorU(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-template <typename T>
-T* ErrorP(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-static std::unique_ptr<ExprAST> ParseExpression();
-
-/// identifierexpr
-/// ::= identifier
-/// ::= identifier '(' expression* ')'
-static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
- std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
- if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(IdName);
-
- // Call.
- getNextToken(); // eat (
- std::vector<std::unique_ptr<ExprAST>> Args;
- if (CurTok != ')') {
- while (1) {
- auto Arg = ParseExpression();
- if (!Arg) return nullptr;
- Args.push_back(std::move(Arg));
-
- if (CurTok == ')') break;
-
- if (CurTok != ',')
- return ErrorU<CallExprAST>("Expected ')' or ',' in argument list");
- getNextToken();
- }
- }
-
- // Eat the ')'.
- getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-
-/// numberexpr ::= number
-static std::unique_ptr<NumberExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return Result;
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return ErrorU<ExprAST>("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
-/// ifexpr ::= 'if' expression 'then' expression 'else' expression
-static std::unique_ptr<ExprAST> ParseIfExpr() {
- getNextToken(); // eat the if.
-
- // condition.
- auto Cond = ParseExpression();
- if (!Cond)
- return nullptr;
-
- if (CurTok != tok_then)
- return ErrorU<ExprAST>("expected then");
- getNextToken(); // eat the then
-
- auto Then = ParseExpression();
- if (!Then)
- return nullptr;
-
- if (CurTok != tok_else)
- return ErrorU<ExprAST>("expected else");
-
- getNextToken();
-
- auto Else = ParseExpression();
- if (!Else)
- return nullptr;
-
- return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
- std::move(Else));
-}
-
-/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
-static std::unique_ptr<ForExprAST> ParseForExpr() {
- getNextToken(); // eat the for.
-
- if (CurTok != tok_identifier)
- return ErrorU<ForExprAST>("expected identifier after for");
-
- std::string IdName = IdentifierStr;
- getNextToken(); // eat identifier.
-
- if (CurTok != '=')
- return ErrorU<ForExprAST>("expected '=' after for");
- getNextToken(); // eat '='.
-
- auto Start = ParseExpression();
- if (!Start)
- return nullptr;
- if (CurTok != ',')
- return ErrorU<ForExprAST>("expected ',' after for start value");
- getNextToken();
-
- auto End = ParseExpression();
- if (!End)
- return nullptr;
-
- // The step value is optional.
- std::unique_ptr<ExprAST> Step;
- if (CurTok == ',') {
- getNextToken();
- Step = ParseExpression();
- if (!Step)
- return nullptr;
- }
-
- if (CurTok != tok_in)
- return ErrorU<ForExprAST>("expected 'in' after for");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (Body)
- return nullptr;
-
- return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
- std::move(Step), std::move(Body));
-}
-
-/// varexpr ::= 'var' identifier ('=' expression)?
-// (',' identifier ('=' expression)?)* 'in' expression
-static std::unique_ptr<VarExprAST> ParseVarExpr() {
- getNextToken(); // eat the var.
-
- VarExprAST::BindingList VarBindings;
-
- // At least one variable name is required.
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier after var");
-
- while (1) {
- std::string Name = IdentifierStr;
- getNextToken(); // eat identifier.
-
- // Read the optional initializer.
- std::unique_ptr<ExprAST> Init;
- if (CurTok == '=') {
- getNextToken(); // eat the '='.
-
- Init = ParseExpression();
- if (!Init)
- return nullptr;
- }
-
- VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init)));
-
- // End of var list, exit loop.
- if (CurTok != ',') break;
- getNextToken(); // eat the ','.
-
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier list after var");
- }
-
- // At this point, we have to have 'in'.
- if (CurTok != tok_in)
- return ErrorU<VarExprAST>("expected 'in' keyword after 'var'");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (!Body)
- return nullptr;
-
- return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body));
-}
-
-/// primary
-/// ::= identifierexpr
-/// ::= numberexpr
-/// ::= parenexpr
-/// ::= ifexpr
-/// ::= forexpr
-/// ::= varexpr
-static std::unique_ptr<ExprAST> ParsePrimary() {
- switch (CurTok) {
- default: return ErrorU<ExprAST>("unknown token when expecting an expression");
- case tok_identifier: return ParseIdentifierExpr();
- case tok_number: return ParseNumberExpr();
- case '(': return ParseParenExpr();
- case tok_if: return ParseIfExpr();
- case tok_for: return ParseForExpr();
- case tok_var: return ParseVarExpr();
- }
-}
-
-/// unary
-/// ::= primary
-/// ::= '!' unary
-static std::unique_ptr<ExprAST> ParseUnary() {
- // If the current token is not an operator, it must be a primary expr.
- if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
- return ParsePrimary();
-
- // If this is a unary operator, read it.
- int Opc = CurTok;
- getNextToken();
- if (auto Operand = ParseUnary())
- return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
- return nullptr;
-}
-
-/// binoprhs
-/// ::= ('+' unary)*
-static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
- std::unique_ptr<ExprAST> LHS) {
- // If this is a binop, find its precedence.
- while (1) {
- int TokPrec = GetTokPrecedence();
-
- // If this is a binop that binds at least as tightly as the current binop,
- // consume it, otherwise we are done.
- if (TokPrec < ExprPrec)
- return LHS;
-
- // Okay, we know this is a binop.
- int BinOp = CurTok;
- getNextToken(); // eat binop
-
- // Parse the unary expression after the binary operator.
- auto RHS = ParseUnary();
- if (!RHS)
- return nullptr;
-
- // If BinOp binds less tightly with RHS than the operator after RHS, let
- // the pending operator take RHS as its LHS.
- int NextPrec = GetTokPrecedence();
- if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
- if (!RHS)
- return nullptr;
- }
-
- // Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
- }
-}
-
-/// expression
-/// ::= unary binoprhs
-///
-static std::unique_ptr<ExprAST> ParseExpression() {
- auto LHS = ParseUnary();
- if (!LHS)
- return nullptr;
-
- return ParseBinOpRHS(0, std::move(LHS));
-}
-
-/// prototype
-/// ::= id '(' id* ')'
-/// ::= binary LETTER number? (id, id)
-/// ::= unary LETTER (id)
-static std::unique_ptr<PrototypeAST> ParsePrototype() {
- std::string FnName;
-
- unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
- unsigned BinaryPrecedence = 30;
-
- switch (CurTok) {
- default:
- return ErrorU<PrototypeAST>("Expected function name in prototype");
- case tok_identifier:
- FnName = IdentifierStr;
- Kind = 0;
- getNextToken();
- break;
- case tok_unary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected unary operator");
- FnName = "unary";
- FnName += (char)CurTok;
- Kind = 1;
- getNextToken();
- break;
- case tok_binary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected binary operator");
- FnName = "binary";
- FnName += (char)CurTok;
- Kind = 2;
- getNextToken();
-
- // Read the precedence if present.
- if (CurTok == tok_number) {
- if (NumVal < 1 || NumVal > 100)
- return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100");
- BinaryPrecedence = (unsigned)NumVal;
- getNextToken();
- }
- break;
- }
-
- if (CurTok != '(')
- return ErrorU<PrototypeAST>("Expected '(' in prototype");
-
- std::vector<std::string> ArgNames;
- while (getNextToken() == tok_identifier)
- ArgNames.push_back(IdentifierStr);
- if (CurTok != ')')
- return ErrorU<PrototypeAST>("Expected ')' in prototype");
-
- // success.
- getNextToken(); // eat ')'.
-
- // Verify right number of names for operator.
- if (Kind && ArgNames.size() != Kind)
- return ErrorU<PrototypeAST>("Invalid number of operands for operator");
-
- return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
- BinaryPrecedence);
-}
-
-/// definition ::= 'def' prototype expression
-static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
- auto Proto = ParsePrototype();
- if (!Proto)
- return nullptr;
-
- if (auto Body = ParseExpression())
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body));
- return nullptr;
-}
-
-/// toplevelexpr ::= expression
-static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- if (auto E = ParseExpression()) {
- // Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
- }
- return nullptr;
-}
-
-/// external ::= 'extern' prototype
-static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
- return ParsePrototype();
-}
-
-//===----------------------------------------------------------------------===//
-// Code Generation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Obviously we can do better than this
-std::string GenerateUniqueName(const std::string &Root) {
- static int i = 0;
- std::ostringstream NameStream;
- NameStream << Root << ++i;
- return NameStream.str();
-}
-
-std::string MakeLegalFunctionName(std::string Name)
-{
- std::string NewName;
- assert(!Name.empty() && "Base name must not be empty");
-
- // Start with what we have
- NewName = Name;
-
- // Look for a numberic first character
- if (NewName.find_first_of("0123456789") == 0) {
- NewName.insert(0, 1, 'n');
- }
-
- // Replace illegal characters with their ASCII equivalent
- std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- size_t pos;
- while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {
- std::ostringstream NumStream;
- NumStream << (int)NewName.at(pos);
- NewName = NewName.replace(pos, 1, NumStream.str());
- }
-
- return NewName;
-}
-
-class SessionContext {
-public:
- SessionContext(LLVMContext &C)
- : Context(C), TM(EngineBuilder().selectTarget()) {}
- LLVMContext& getLLVMContext() const { return Context; }
- TargetMachine& getTarget() { return *TM; }
- void addPrototypeAST(std::unique_ptr<PrototypeAST> P);
- PrototypeAST* getPrototypeAST(const std::string &Name);
-private:
- typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap;
-
- LLVMContext &Context;
- std::unique_ptr<TargetMachine> TM;
-
- PrototypeMap Prototypes;
-};
-
-void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) {
- Prototypes[P->Name] = std::move(P);
-}
-
-PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) {
- PrototypeMap::iterator I = Prototypes.find(Name);
- if (I != Prototypes.end())
- return I->second.get();
- return nullptr;
-}
-
-class IRGenContext {
-public:
-
- IRGenContext(SessionContext &S)
- : Session(S),
- M(new Module(GenerateUniqueName("jit_module_"),
- Session.getLLVMContext())),
- Builder(Session.getLLVMContext()) {
- M->setDataLayout(Session.getTarget().createDataLayout());
- }
-
- SessionContext& getSession() { return Session; }
- Module& getM() const { return *M; }
- std::unique_ptr<Module> takeM() { return std::move(M); }
- IRBuilder<>& getBuilder() { return Builder; }
- LLVMContext& getLLVMContext() { return Session.getLLVMContext(); }
- Function* getPrototype(const std::string &Name);
-
- std::map<std::string, AllocaInst*> NamedValues;
-private:
- SessionContext &Session;
- std::unique_ptr<Module> M;
- IRBuilder<> Builder;
-};
-
-Function* IRGenContext::getPrototype(const std::string &Name) {
- if (Function *ExistingProto = M->getFunction(Name))
- return ExistingProto;
- if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name))
- return ProtoAST->IRGen(*this);
- return nullptr;
-}
-
-/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
-/// the function. This is used for mutable variables etc.
-static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
- const std::string &VarName) {
- IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
- TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
-}
-
-Value *NumberExprAST::IRGen(IRGenContext &C) const {
- return ConstantFP::get(C.getLLVMContext(), APFloat(Val));
-}
-
-Value *VariableExprAST::IRGen(IRGenContext &C) const {
- // Look this variable up in the function.
- Value *V = C.NamedValues[Name];
-
- if (!V)
- return ErrorP<Value>("Unknown variable name '" + Name + "'");
-
- // Load the value.
- return C.getBuilder().CreateLoad(V, Name.c_str());
-}
-
-Value *UnaryExprAST::IRGen(IRGenContext &C) const {
- if (Value *OperandV = Operand->IRGen(C)) {
- std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode);
- if (Function *F = C.getPrototype(FnName))
- return C.getBuilder().CreateCall(F, OperandV, "unop");
- return ErrorP<Value>("Unknown unary operator");
- }
-
- // Could not codegen operand - return null.
- return nullptr;
-}
-
-Value *BinaryExprAST::IRGen(IRGenContext &C) const {
- // Special case '=' because we don't want to emit the LHS as an expression.
- if (Op == '=') {
- // Assignment requires the LHS to be an identifier.
- auto &LHSVar = static_cast<VariableExprAST &>(*LHS);
- // Codegen the RHS.
- Value *Val = RHS->IRGen(C);
- if (!Val) return nullptr;
-
- // Look up the name.
- if (auto Variable = C.NamedValues[LHSVar.Name]) {
- C.getBuilder().CreateStore(Val, Variable);
- return Val;
- }
- return ErrorP<Value>("Unknown variable name");
- }
-
- Value *L = LHS->IRGen(C);
- Value *R = RHS->IRGen(C);
- if (!L || !R) return nullptr;
-
- switch (Op) {
- case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp");
- case '-': return C.getBuilder().CreateFSub(L, R, "subtmp");
- case '*': return C.getBuilder().CreateFMul(L, R, "multmp");
- case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp");
- case '<':
- L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp");
- // Convert bool 0/1 to double 0.0 or 1.0
- return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
- default: break;
- }
-
- // If it wasn't a builtin binary operator, it must be a user defined one. Emit
- // a call to it.
- std::string FnName = MakeLegalFunctionName(std::string("binary")+Op);
- if (Function *F = C.getPrototype(FnName)) {
- Value *Ops[] = { L, R };
- return C.getBuilder().CreateCall(F, Ops, "binop");
- }
-
- return ErrorP<Value>("Unknown binary operator");
-}
-
-Value *CallExprAST::IRGen(IRGenContext &C) const {
- // Look up the name in the global module table.
- if (auto CalleeF = C.getPrototype(CalleeName)) {
- // If argument mismatch error.
- if (CalleeF->arg_size() != Args.size())
- return ErrorP<Value>("Incorrect # arguments passed");
-
- std::vector<Value*> ArgsV;
- for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- ArgsV.push_back(Args[i]->IRGen(C));
- if (!ArgsV.back()) return nullptr;
- }
-
- return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp");
- }
-
- return ErrorP<Value>("Unknown function referenced");
-}
-
-Value *IfExprAST::IRGen(IRGenContext &C) const {
- Value *CondV = Cond->IRGen(C);
- if (!CondV) return nullptr;
-
- // Convert condition to a bool by comparing equal to 0.0.
- ConstantFP *FPZero =
- ConstantFP::get(C.getLLVMContext(), APFloat(0.0));
- CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond");
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create blocks for the then and else cases. Insert the 'then' block at the
- // end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont");
-
- C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB);
-
- // Emit then value.
- C.getBuilder().SetInsertPoint(ThenBB);
-
- Value *ThenV = Then->IRGen(C);
- if (!ThenV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
- ThenBB = C.getBuilder().GetInsertBlock();
-
- // Emit else block.
- TheFunction->getBasicBlockList().push_back(ElseBB);
- C.getBuilder().SetInsertPoint(ElseBB);
-
- Value *ElseV = Else->IRGen(C);
- if (!ElseV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
- ElseBB = C.getBuilder().GetInsertBlock();
-
- // Emit merge block.
- TheFunction->getBasicBlockList().push_back(MergeBB);
- C.getBuilder().SetInsertPoint(MergeBB);
- PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
- PN->addIncoming(ThenV, ThenBB);
- PN->addIncoming(ElseV, ElseBB);
- return PN;
-}
-
-Value *ForExprAST::IRGen(IRGenContext &C) const {
- // Output this as:
- // var = alloca double
- // ...
- // start = startexpr
- // store start -> var
- // goto loop
- // loop:
- // ...
- // bodyexpr
- // ...
- // loopend:
- // step = stepexpr
- // endcond = endexpr
- //
- // curvar = load var
- // nextvar = curvar + step
- // store nextvar -> var
- // br endcond, loop, endloop
- // outloop:
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create an alloca for the variable in the entry block.
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
-
- // Emit the start code first, without 'variable' in scope.
- Value *StartVal = Start->IRGen(C);
- if (!StartVal) return nullptr;
-
- // Store the value into the alloca.
- C.getBuilder().CreateStore(StartVal, Alloca);
-
- // Make the new basic block for the loop header, inserting after current
- // block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
- // Insert an explicit fall through from the current block to the LoopBB.
- C.getBuilder().CreateBr(LoopBB);
-
- // Start insertion in LoopBB.
- C.getBuilder().SetInsertPoint(LoopBB);
-
- // Within the loop, the variable is defined equal to the PHI node. If it
- // shadows an existing variable, we have to restore it, so save it now.
- AllocaInst *OldVal = C.NamedValues[VarName];
- C.NamedValues[VarName] = Alloca;
-
- // Emit the body of the loop. This, like any other expr, can change the
- // current BB. Note that we ignore the value computed by the body, but don't
- // allow an error.
- if (!Body->IRGen(C))
- return nullptr;
-
- // Emit the step value.
- Value *StepVal;
- if (Step) {
- StepVal = Step->IRGen(C);
- if (!StepVal) return nullptr;
- } else {
- // If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
- }
-
- // Compute the end condition.
- Value *EndCond = End->IRGen(C);
- if (!EndCond) return nullptr;
-
- // Reload, increment, and restore the alloca. This handles the case where
- // the body of the loop mutates the variable.
- Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str());
- Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar");
- C.getBuilder().CreateStore(NextVar, Alloca);
-
- // Convert condition to a bool by comparing equal to 0.0.
- EndCond = C.getBuilder().CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
- // Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
- // Insert the conditional branch into the end of LoopEndBB.
- C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB);
-
- // Any new code will be inserted in AfterBB.
- C.getBuilder().SetInsertPoint(AfterBB);
-
- // Restore the unshadowed variable.
- if (OldVal)
- C.NamedValues[VarName] = OldVal;
- else
- C.NamedValues.erase(VarName);
-
- // for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
-}
-
-Value *VarExprAST::IRGen(IRGenContext &C) const {
- std::vector<AllocaInst *> OldBindings;
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Register all variables and emit their initializer.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) {
- auto &VarName = VarBindings[i].first;
- auto &Init = VarBindings[i].second;
-
- // Emit the initializer before adding the variable to scope, this prevents
- // the initializer from referencing the variable itself, and permits stuff
- // like this:
- // var a = 1 in
- // var a = a in ... # refers to outer 'a'.
- Value *InitVal;
- if (Init) {
- InitVal = Init->IRGen(C);
- if (!InitVal) return nullptr;
- } else // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
-
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- C.getBuilder().CreateStore(InitVal, Alloca);
-
- // Remember the old variable binding so that we can restore the binding when
- // we unrecurse.
- OldBindings.push_back(C.NamedValues[VarName]);
-
- // Remember this binding.
- C.NamedValues[VarName] = Alloca;
- }
-
- // Codegen the body, now that all vars are in scope.
- Value *BodyVal = Body->IRGen(C);
- if (!BodyVal) return nullptr;
-
- // Pop all our variables from scope.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i)
- C.NamedValues[VarBindings[i].first] = OldBindings[i];
-
- // Return the body computation.
- return BodyVal;
-}
-
-Function *PrototypeAST::IRGen(IRGenContext &C) const {
- std::string FnName = MakeLegalFunctionName(Name);
-
- // Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
- Function *F = Function::Create(FT, Function::ExternalLinkage, FnName,
- &C.getM());
-
- // If F conflicted, there was already something named 'FnName'. If it has a
- // body, don't allow redefinition or reextern.
- if (F->getName() != FnName) {
- // Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = C.getM().getFunction(Name);
-
- // If F already has a body, reject this.
- if (!F->empty()) {
- ErrorP<Function>("redefinition of function");
- return nullptr;
- }
-
- // If F took a different number of args, reject.
- if (F->arg_size() != Args.size()) {
- ErrorP<Function>("redefinition of function with different # args");
- return nullptr;
- }
- }
-
- // Set names for all arguments.
- unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
- ++AI, ++Idx)
- AI->setName(Args[Idx]);
-
- return F;
-}
-
-/// CreateArgumentAllocas - Create an alloca for each argument and register the
-/// argument in the symbol table so that references to it will succeed.
-void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) {
- Function::arg_iterator AI = F->arg_begin();
- for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
- // Create an alloca for this variable.
- AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
-
- // Store the initial value into the alloca.
- C.getBuilder().CreateStore(&*AI, Alloca);
-
- // Add arguments to variable symbol table.
- C.NamedValues[Args[Idx]] = Alloca;
- }
-}
-
-Function *FunctionAST::IRGen(IRGenContext &C) const {
- C.NamedValues.clear();
-
- Function *TheFunction = Proto->IRGen(C);
- if (!TheFunction)
- return nullptr;
-
- // If this is an operator, install it.
- if (Proto->isBinaryOp())
- BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence;
-
- // Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
- C.getBuilder().SetInsertPoint(BB);
-
- // Add all arguments to the symbol table and create their allocas.
- Proto->CreateArgumentAllocas(TheFunction, C);
-
- if (Value *RetVal = Body->IRGen(C)) {
- // Finish off the function.
- C.getBuilder().CreateRet(RetVal);
-
- // Validate the generated code, checking for consistency.
- verifyFunction(*TheFunction);
-
- return TheFunction;
- }
-
- // Error reading body, remove function.
- TheFunction->eraseFromParent();
-
- if (Proto->isBinaryOp())
- BinopPrecedence.erase(Proto->getOperatorName());
- return nullptr;
-}
-
-//===----------------------------------------------------------------------===//
-// Top-Level parsing and JIT Driver
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<llvm::Module> IRGen(SessionContext &S,
- const FunctionAST &F) {
- IRGenContext C(S);
- auto LF = F.IRGen(C);
- if (!LF)
- return nullptr;
-#ifndef MINIMAL_STDERR_OUTPUT
- fprintf(stderr, "Read function definition:");
- LF->dump();
-#endif
- return C.takeM();
-}
-
-template <typename T>
-static std::vector<T> singletonSet(T t) {
- std::vector<T> Vec;
- Vec.push_back(std::move(t));
- return Vec;
-}
-
-class KaleidoscopeJIT {
-public:
- typedef ObjectLinkingLayer<> ObjLayerT;
- typedef IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
-
- typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT;
-
- KaleidoscopeJIT(SessionContext &Session)
- : DL(Session.getTarget().createDataLayout()),
- CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())),
- LazyEmitLayer(CompileLayer) {}
-
- std::string mangle(const std::string &Name) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
- }
- return MangledName;
- }
-
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- // We need a memory manager to allocate memory and resolve symbols for this
- // new module. Create one that resolves symbols by looking back into the
- // JIT.
- auto Resolver = createLambdaResolver(
- [&](const std::string &Name) {
- if (auto Sym = findSymbol(Name))
- return RuntimeDyld::SymbolInfo(Sym.getAddress(),
- Sym.getFlags());
- return RuntimeDyld::SymbolInfo(nullptr);
- },
- [](const std::string &S) { return nullptr; } );
-
- return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- make_unique<SectionMemoryManager>(),
- std::move(Resolver));
- }
-
- void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
-
- JITSymbol findSymbol(const std::string &Name) {
- return LazyEmitLayer.findSymbol(Name, true);
- }
-
- JITSymbol findUnmangledSymbol(const std::string Name) {
- return findSymbol(mangle(Name));
- }
-
-private:
- const DataLayout DL;
- ObjLayerT ObjectLayer;
- CompileLayerT CompileLayer;
- LazyEmitLayerT LazyEmitLayer;
-};
-
-static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) {
- if (auto F = ParseDefinition()) {
- if (auto M = IRGen(S, *F)) {
- S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto));
- J.addModule(std::move(M));
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleExtern(SessionContext &S) {
- if (auto P = ParseExtern())
- S.addPrototypeAST(std::move(P));
- else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
- // Evaluate a top-level expression into an anonymous function.
- if (auto F = ParseTopLevelExpr()) {
- IRGenContext C(S);
- if (auto ExprFunc = F->IRGen(C)) {
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "Expression function:\n";
- ExprFunc->dump();
-#endif
- // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove
- // this module as soon as we've executed Function ExprFunc.
- auto H = J.addModule(C.takeM());
-
- // Get the address of the JIT'd function in memory.
- auto ExprSymbol = J.findUnmangledSymbol("__anon_expr");
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
-#ifdef MINIMAL_STDERR_OUTPUT
- FP();
-#else
- std::cerr << "Evaluated to " << FP() << "\n";
-#endif
-
- // Remove the function.
- J.removeModule(H);
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-/// top ::= definition | external | expression | ';'
-static void MainLoop() {
- SessionContext S(getGlobalContext());
- KaleidoscopeJIT J(S);
-
- while (1) {
- switch (CurTok) {
- case tok_eof: return;
- case ';': getNextToken(); continue; // ignore top-level semicolons.
- case tok_def: HandleDefinition(S, J); break;
- case tok_extern: HandleExtern(S); break;
- default: HandleTopLevelExpression(S, J); break;
- }
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- }
-}
-
-//===----------------------------------------------------------------------===//
-// "Library" functions that can be "extern'd" from user code.
-//===----------------------------------------------------------------------===//
-
-/// putchard - putchar that takes a double and returns 0.
-extern "C"
-double putchard(double X) {
- putchar((char)X);
- return 0;
-}
-
-/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C"
-double printd(double X) {
- printf("%f", X);
- return 0;
-}
-
-extern "C"
-double printlf() {
- printf("\n");
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// Main driver code.
-//===----------------------------------------------------------------------===//
-
-int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
- // Install standard binary operators.
- // 1 is lowest precedence.
- BinopPrecedence['='] = 2;
- BinopPrecedence['<'] = 10;
- BinopPrecedence['+'] = 20;
- BinopPrecedence['-'] = 20;
- BinopPrecedence['/'] = 40;
- BinopPrecedence['*'] = 40; // highest.
-
- // Prime the first token.
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- getNextToken();
-
- std::cerr << std::fixed;
-
- // Run the main "interpreter loop" now.
- MainLoop();
-
- return 0;
-}
diff --git a/examples/Kaleidoscope/Orc/lazy_irgen/CMakeLists.txt b/examples/Kaleidoscope/Orc/lazy_irgen/CMakeLists.txt
deleted file mode 100644
index 44886818e0f0a..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_irgen/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- Core
- ExecutionEngine
- Object
- RuntimeDyld
- Support
- native
- )
-
-add_kaleidoscope_chapter(Kaleidoscope-Orc-lazy_irgen
- toy.cpp
- )
diff --git a/examples/Kaleidoscope/Orc/lazy_irgen/Makefile b/examples/Kaleidoscope/Orc/lazy_irgen/Makefile
deleted file mode 100644
index 5536314f2a309..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_irgen/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-UNAME := $(shell uname -s)
-
-ifeq ($(UNAME),Darwin)
- CXX := xcrun --sdk macosx clang++
-else
- CXX := clang++
-endif
-
-LLVM_CXXFLAGS := $(shell llvm-config --cxxflags)
-LLVM_LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core orcjit native)
-
-toy: toy.cpp
- $(CXX) $(LLVM_CXXFLAGS) -Wall -std=c++11 -g -O0 -rdynamic -fno-rtti -o toy toy.cpp $(LLVM_LDFLAGS)
-
-.PHONY: clean
-clean:
- rm -f toy
diff --git a/examples/Kaleidoscope/Orc/lazy_irgen/README.txt b/examples/Kaleidoscope/Orc/lazy_irgen/README.txt
deleted file mode 100644
index 9aaa431712dc1..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_irgen/README.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-//===----------------------------------------------------------------------===/
-// Kaleidoscope with Orc - Lazy IRGen Version
-//===----------------------------------------------------------------------===//
-
-This version of Kaleidoscope with Orc demonstrates lazy IR-generation.
-Building on the lazy-codegen version of the tutorial, this version reduces the
-amount of up-front work that must be done by lazily IRgen'ing ASTs. When a
-function definition is entered, its AST is added to a map of available
-definitions. No IRGen is performed at this point and nothing is added to the JIT.
-When attempting to resolve symbol addresses, the lambda in
-KaleidoscopeJIT::getSymbolAddress will scan the AST map and generate IR on the
-fly.
-
-This directory contains a Makefile that allows the code to be built in a
-standalone manner, independent of the larger LLVM build infrastructure. To build
-the program you will need to have 'clang++' and 'llvm-config' in your path.
diff --git a/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp b/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp
deleted file mode 100644
index ebaff49e89b25..0000000000000
--- a/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp
+++ /dev/null
@@ -1,1370 +0,0 @@
-#include "llvm/Analysis/Passes.h"
-#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
-#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
-#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
-#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Transforms/Scalar.h"
-#include <cctype>
-#include <iomanip>
-#include <iostream>
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::orc;
-
-//===----------------------------------------------------------------------===//
-// Lexer
-//===----------------------------------------------------------------------===//
-
-// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
-// of these for known things.
-enum Token {
- tok_eof = -1,
-
- // commands
- tok_def = -2, tok_extern = -3,
-
- // primary
- tok_identifier = -4, tok_number = -5,
-
- // control
- tok_if = -6, tok_then = -7, tok_else = -8,
- tok_for = -9, tok_in = -10,
-
- // operators
- tok_binary = -11, tok_unary = -12,
-
- // var definition
- tok_var = -13
-};
-
-static std::string IdentifierStr; // Filled in if tok_identifier
-static double NumVal; // Filled in if tok_number
-
-/// gettok - Return the next token from standard input.
-static int gettok() {
- static int LastChar = ' ';
-
- // Skip any whitespace.
- while (isspace(LastChar))
- LastChar = getchar();
-
- if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
- IdentifierStr = LastChar;
- while (isalnum((LastChar = getchar())))
- IdentifierStr += LastChar;
-
- if (IdentifierStr == "def") return tok_def;
- if (IdentifierStr == "extern") return tok_extern;
- if (IdentifierStr == "if") return tok_if;
- if (IdentifierStr == "then") return tok_then;
- if (IdentifierStr == "else") return tok_else;
- if (IdentifierStr == "for") return tok_for;
- if (IdentifierStr == "in") return tok_in;
- if (IdentifierStr == "binary") return tok_binary;
- if (IdentifierStr == "unary") return tok_unary;
- if (IdentifierStr == "var") return tok_var;
- return tok_identifier;
- }
-
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
- std::string NumStr;
- do {
- NumStr += LastChar;
- LastChar = getchar();
- } while (isdigit(LastChar) || LastChar == '.');
-
- NumVal = strtod(NumStr.c_str(), nullptr);
- return tok_number;
- }
-
- if (LastChar == '#') {
- // Comment until end of line.
- do LastChar = getchar();
- while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
-
- if (LastChar != EOF)
- return gettok();
- }
-
- // Check for end of file. Don't eat the EOF.
- if (LastChar == EOF)
- return tok_eof;
-
- // Otherwise, just return the character as its ascii value.
- int ThisChar = LastChar;
- LastChar = getchar();
- return ThisChar;
-}
-
-//===----------------------------------------------------------------------===//
-// Abstract Syntax Tree (aka Parse Tree)
-//===----------------------------------------------------------------------===//
-
-class IRGenContext;
-
-/// ExprAST - Base class for all expression nodes.
-struct ExprAST {
- virtual ~ExprAST() {}
- virtual Value *IRGen(IRGenContext &C) const = 0;
-};
-
-/// NumberExprAST - Expression class for numeric literals like "1.0".
-struct NumberExprAST : public ExprAST {
- NumberExprAST(double Val) : Val(Val) {}
- Value *IRGen(IRGenContext &C) const override;
-
- double Val;
-};
-
-/// VariableExprAST - Expression class for referencing a variable, like "a".
-struct VariableExprAST : public ExprAST {
- VariableExprAST(std::string Name) : Name(std::move(Name)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::string Name;
-};
-
-/// UnaryExprAST - Expression class for a unary operator.
-struct UnaryExprAST : public ExprAST {
- UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
- : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Opcode;
- std::unique_ptr<ExprAST> Operand;
-};
-
-/// BinaryExprAST - Expression class for a binary operator.
-struct BinaryExprAST : public ExprAST {
- BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
- std::unique_ptr<ExprAST> RHS)
- : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- char Op;
- std::unique_ptr<ExprAST> LHS, RHS;
-};
-
-/// CallExprAST - Expression class for function calls.
-struct CallExprAST : public ExprAST {
- CallExprAST(std::string CalleeName,
- std::vector<std::unique_ptr<ExprAST>> Args)
- : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string CalleeName;
- std::vector<std::unique_ptr<ExprAST>> Args;
-};
-
-/// IfExprAST - Expression class for if/then/else.
-struct IfExprAST : public ExprAST {
- IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
- std::unique_ptr<ExprAST> Else)
- : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
- Value *IRGen(IRGenContext &C) const override;
-
- std::unique_ptr<ExprAST> Cond, Then, Else;
-};
-
-/// ForExprAST - Expression class for for/in.
-struct ForExprAST : public ExprAST {
- ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start,
- std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
- std::unique_ptr<ExprAST> Body)
- : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)),
- Step(std::move(Step)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- std::string VarName;
- std::unique_ptr<ExprAST> Start, End, Step, Body;
-};
-
-/// VarExprAST - Expression class for var/in
-struct VarExprAST : public ExprAST {
- typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding;
- typedef std::vector<Binding> BindingList;
-
- VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body)
- : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {}
-
- Value *IRGen(IRGenContext &C) const override;
-
- BindingList VarBindings;
- std::unique_ptr<ExprAST> Body;
-};
-
-/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
-struct PrototypeAST {
- PrototypeAST(std::string Name, std::vector<std::string> Args,
- bool IsOperator = false, unsigned Precedence = 0)
- : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Precedence) {}
-
- Function *IRGen(IRGenContext &C) const;
- void CreateArgumentAllocas(Function *F, IRGenContext &C);
-
- bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
- bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
-
- char getOperatorName() const {
- assert(isUnaryOp() || isBinaryOp());
- return Name[Name.size()-1];
- }
-
- std::string Name;
- std::vector<std::string> Args;
- bool IsOperator;
- unsigned Precedence; // Precedence if a binary op.
-};
-
-/// FunctionAST - This class represents a function definition itself.
-struct FunctionAST {
- FunctionAST(std::unique_ptr<PrototypeAST> Proto,
- std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
-
- Function *IRGen(IRGenContext &C) const;
-
- std::unique_ptr<PrototypeAST> Proto;
- std::unique_ptr<ExprAST> Body;
-};
-
-//===----------------------------------------------------------------------===//
-// Parser
-//===----------------------------------------------------------------------===//
-
-/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
-/// token the parser is looking at. getNextToken reads another token from the
-/// lexer and updates CurTok with its results.
-static int CurTok;
-static int getNextToken() {
- return CurTok = gettok();
-}
-
-/// BinopPrecedence - This holds the precedence for each binary operator that is
-/// defined.
-static std::map<char, int> BinopPrecedence;
-
-/// GetTokPrecedence - Get the precedence of the pending binary operator token.
-static int GetTokPrecedence() {
- if (!isascii(CurTok))
- return -1;
-
- // Make sure it's a declared binop.
- int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
- return TokPrec;
-}
-
-template <typename T>
-std::unique_ptr<T> ErrorU(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-template <typename T>
-T* ErrorP(const std::string &Str) {
- std::cerr << "Error: " << Str << "\n";
- return nullptr;
-}
-
-static std::unique_ptr<ExprAST> ParseExpression();
-
-/// identifierexpr
-/// ::= identifier
-/// ::= identifier '(' expression* ')'
-static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
- std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
- if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(IdName);
-
- // Call.
- getNextToken(); // eat (
- std::vector<std::unique_ptr<ExprAST>> Args;
- if (CurTok != ')') {
- while (1) {
- auto Arg = ParseExpression();
- if (!Arg) return nullptr;
- Args.push_back(std::move(Arg));
-
- if (CurTok == ')') break;
-
- if (CurTok != ',')
- return ErrorU<CallExprAST>("Expected ')' or ',' in argument list");
- getNextToken();
- }
- }
-
- // Eat the ')'.
- getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-
-/// numberexpr ::= number
-static std::unique_ptr<NumberExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return Result;
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return ErrorU<ExprAST>("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
-/// ifexpr ::= 'if' expression 'then' expression 'else' expression
-static std::unique_ptr<ExprAST> ParseIfExpr() {
- getNextToken(); // eat the if.
-
- // condition.
- auto Cond = ParseExpression();
- if (!Cond)
- return nullptr;
-
- if (CurTok != tok_then)
- return ErrorU<ExprAST>("expected then");
- getNextToken(); // eat the then
-
- auto Then = ParseExpression();
- if (!Then)
- return nullptr;
-
- if (CurTok != tok_else)
- return ErrorU<ExprAST>("expected else");
-
- getNextToken();
-
- auto Else = ParseExpression();
- if (!Else)
- return nullptr;
-
- return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
- std::move(Else));
-}
-
-/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
-static std::unique_ptr<ForExprAST> ParseForExpr() {
- getNextToken(); // eat the for.
-
- if (CurTok != tok_identifier)
- return ErrorU<ForExprAST>("expected identifier after for");
-
- std::string IdName = IdentifierStr;
- getNextToken(); // eat identifier.
-
- if (CurTok != '=')
- return ErrorU<ForExprAST>("expected '=' after for");
- getNextToken(); // eat '='.
-
- auto Start = ParseExpression();
- if (!Start)
- return nullptr;
- if (CurTok != ',')
- return ErrorU<ForExprAST>("expected ',' after for start value");
- getNextToken();
-
- auto End = ParseExpression();
- if (!End)
- return nullptr;
-
- // The step value is optional.
- std::unique_ptr<ExprAST> Step;
- if (CurTok == ',') {
- getNextToken();
- Step = ParseExpression();
- if (!Step)
- return nullptr;
- }
-
- if (CurTok != tok_in)
- return ErrorU<ForExprAST>("expected 'in' after for");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (Body)
- return nullptr;
-
- return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
- std::move(Step), std::move(Body));
-}
-
-/// varexpr ::= 'var' identifier ('=' expression)?
-// (',' identifier ('=' expression)?)* 'in' expression
-static std::unique_ptr<VarExprAST> ParseVarExpr() {
- getNextToken(); // eat the var.
-
- VarExprAST::BindingList VarBindings;
-
- // At least one variable name is required.
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier after var");
-
- while (1) {
- std::string Name = IdentifierStr;
- getNextToken(); // eat identifier.
-
- // Read the optional initializer.
- std::unique_ptr<ExprAST> Init;
- if (CurTok == '=') {
- getNextToken(); // eat the '='.
-
- Init = ParseExpression();
- if (!Init)
- return nullptr;
- }
-
- VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init)));
-
- // End of var list, exit loop.
- if (CurTok != ',') break;
- getNextToken(); // eat the ','.
-
- if (CurTok != tok_identifier)
- return ErrorU<VarExprAST>("expected identifier list after var");
- }
-
- // At this point, we have to have 'in'.
- if (CurTok != tok_in)
- return ErrorU<VarExprAST>("expected 'in' keyword after 'var'");
- getNextToken(); // eat 'in'.
-
- auto Body = ParseExpression();
- if (!Body)
- return nullptr;
-
- return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body));
-}
-
-/// primary
-/// ::= identifierexpr
-/// ::= numberexpr
-/// ::= parenexpr
-/// ::= ifexpr
-/// ::= forexpr
-/// ::= varexpr
-static std::unique_ptr<ExprAST> ParsePrimary() {
- switch (CurTok) {
- default: return ErrorU<ExprAST>("unknown token when expecting an expression");
- case tok_identifier: return ParseIdentifierExpr();
- case tok_number: return ParseNumberExpr();
- case '(': return ParseParenExpr();
- case tok_if: return ParseIfExpr();
- case tok_for: return ParseForExpr();
- case tok_var: return ParseVarExpr();
- }
-}
-
-/// unary
-/// ::= primary
-/// ::= '!' unary
-static std::unique_ptr<ExprAST> ParseUnary() {
- // If the current token is not an operator, it must be a primary expr.
- if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
- return ParsePrimary();
-
- // If this is a unary operator, read it.
- int Opc = CurTok;
- getNextToken();
- if (auto Operand = ParseUnary())
- return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
- return nullptr;
-}
-
-/// binoprhs
-/// ::= ('+' unary)*
-static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
- std::unique_ptr<ExprAST> LHS) {
- // If this is a binop, find its precedence.
- while (1) {
- int TokPrec = GetTokPrecedence();
-
- // If this is a binop that binds at least as tightly as the current binop,
- // consume it, otherwise we are done.
- if (TokPrec < ExprPrec)
- return LHS;
-
- // Okay, we know this is a binop.
- int BinOp = CurTok;
- getNextToken(); // eat binop
-
- // Parse the unary expression after the binary operator.
- auto RHS = ParseUnary();
- if (!RHS)
- return nullptr;
-
- // If BinOp binds less tightly with RHS than the operator after RHS, let
- // the pending operator take RHS as its LHS.
- int NextPrec = GetTokPrecedence();
- if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
- if (!RHS)
- return nullptr;
- }
-
- // Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
- }
-}
-
-/// expression
-/// ::= unary binoprhs
-///
-static std::unique_ptr<ExprAST> ParseExpression() {
- auto LHS = ParseUnary();
- if (!LHS)
- return nullptr;
-
- return ParseBinOpRHS(0, std::move(LHS));
-}
-
-/// prototype
-/// ::= id '(' id* ')'
-/// ::= binary LETTER number? (id, id)
-/// ::= unary LETTER (id)
-static std::unique_ptr<PrototypeAST> ParsePrototype() {
- std::string FnName;
-
- unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
- unsigned BinaryPrecedence = 30;
-
- switch (CurTok) {
- default:
- return ErrorU<PrototypeAST>("Expected function name in prototype");
- case tok_identifier:
- FnName = IdentifierStr;
- Kind = 0;
- getNextToken();
- break;
- case tok_unary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected unary operator");
- FnName = "unary";
- FnName += (char)CurTok;
- Kind = 1;
- getNextToken();
- break;
- case tok_binary:
- getNextToken();
- if (!isascii(CurTok))
- return ErrorU<PrototypeAST>("Expected binary operator");
- FnName = "binary";
- FnName += (char)CurTok;
- Kind = 2;
- getNextToken();
-
- // Read the precedence if present.
- if (CurTok == tok_number) {
- if (NumVal < 1 || NumVal > 100)
- return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100");
- BinaryPrecedence = (unsigned)NumVal;
- getNextToken();
- }
- break;
- }
-
- if (CurTok != '(')
- return ErrorU<PrototypeAST>("Expected '(' in prototype");
-
- std::vector<std::string> ArgNames;
- while (getNextToken() == tok_identifier)
- ArgNames.push_back(IdentifierStr);
- if (CurTok != ')')
- return ErrorU<PrototypeAST>("Expected ')' in prototype");
-
- // success.
- getNextToken(); // eat ')'.
-
- // Verify right number of names for operator.
- if (Kind && ArgNames.size() != Kind)
- return ErrorU<PrototypeAST>("Invalid number of operands for operator");
-
- return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
- BinaryPrecedence);
-}
-
-/// definition ::= 'def' prototype expression
-static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
- auto Proto = ParsePrototype();
- if (!Proto)
- return nullptr;
-
- if (auto Body = ParseExpression())
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body));
- return nullptr;
-}
-
-/// toplevelexpr ::= expression
-static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- if (auto E = ParseExpression()) {
- // Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());
- return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
- }
- return nullptr;
-}
-
-/// external ::= 'extern' prototype
-static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
- return ParsePrototype();
-}
-
-//===----------------------------------------------------------------------===//
-// Code Generation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Obviously we can do better than this
-std::string GenerateUniqueName(const std::string &Root) {
- static int i = 0;
- std::ostringstream NameStream;
- NameStream << Root << ++i;
- return NameStream.str();
-}
-
-std::string MakeLegalFunctionName(std::string Name)
-{
- std::string NewName;
- assert(!Name.empty() && "Base name must not be empty");
-
- // Start with what we have
- NewName = Name;
-
- // Look for a numberic first character
- if (NewName.find_first_of("0123456789") == 0) {
- NewName.insert(0, 1, 'n');
- }
-
- // Replace illegal characters with their ASCII equivalent
- std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- size_t pos;
- while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {
- std::ostringstream NumStream;
- NumStream << (int)NewName.at(pos);
- NewName = NewName.replace(pos, 1, NumStream.str());
- }
-
- return NewName;
-}
-
-class SessionContext {
-public:
- SessionContext(LLVMContext &C)
- : Context(C), TM(EngineBuilder().selectTarget()) {}
- LLVMContext& getLLVMContext() const { return Context; }
- TargetMachine& getTarget() { return *TM; }
- void addPrototypeAST(std::unique_ptr<PrototypeAST> P);
- PrototypeAST* getPrototypeAST(const std::string &Name);
-private:
- typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap;
-
- LLVMContext &Context;
- std::unique_ptr<TargetMachine> TM;
-
- PrototypeMap Prototypes;
-};
-
-void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) {
- Prototypes[P->Name] = std::move(P);
-}
-
-PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) {
- PrototypeMap::iterator I = Prototypes.find(Name);
- if (I != Prototypes.end())
- return I->second.get();
- return nullptr;
-}
-
-class IRGenContext {
-public:
-
- IRGenContext(SessionContext &S)
- : Session(S),
- M(new Module(GenerateUniqueName("jit_module_"),
- Session.getLLVMContext())),
- Builder(Session.getLLVMContext()) {
- M->setDataLayout(Session.getTarget().createDataLayout());
- }
-
- SessionContext& getSession() { return Session; }
- Module& getM() const { return *M; }
- std::unique_ptr<Module> takeM() { return std::move(M); }
- IRBuilder<>& getBuilder() { return Builder; }
- LLVMContext& getLLVMContext() { return Session.getLLVMContext(); }
- Function* getPrototype(const std::string &Name);
-
- std::map<std::string, AllocaInst*> NamedValues;
-private:
- SessionContext &Session;
- std::unique_ptr<Module> M;
- IRBuilder<> Builder;
-};
-
-Function* IRGenContext::getPrototype(const std::string &Name) {
- if (Function *ExistingProto = M->getFunction(Name))
- return ExistingProto;
- if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name))
- return ProtoAST->IRGen(*this);
- return nullptr;
-}
-
-/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
-/// the function. This is used for mutable variables etc.
-static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
- const std::string &VarName) {
- IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
- TheFunction->getEntryBlock().begin());
- return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr,
- VarName.c_str());
-}
-
-Value *NumberExprAST::IRGen(IRGenContext &C) const {
- return ConstantFP::get(C.getLLVMContext(), APFloat(Val));
-}
-
-Value *VariableExprAST::IRGen(IRGenContext &C) const {
- // Look this variable up in the function.
- Value *V = C.NamedValues[Name];
-
- if (!V)
- return ErrorP<Value>("Unknown variable name '" + Name + "'");
-
- // Load the value.
- return C.getBuilder().CreateLoad(V, Name.c_str());
-}
-
-Value *UnaryExprAST::IRGen(IRGenContext &C) const {
- if (Value *OperandV = Operand->IRGen(C)) {
- std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode);
- if (Function *F = C.getPrototype(FnName))
- return C.getBuilder().CreateCall(F, OperandV, "unop");
- return ErrorP<Value>("Unknown unary operator");
- }
-
- // Could not codegen operand - return null.
- return nullptr;
-}
-
-Value *BinaryExprAST::IRGen(IRGenContext &C) const {
- // Special case '=' because we don't want to emit the LHS as an expression.
- if (Op == '=') {
- // Assignment requires the LHS to be an identifier.
- auto &LHSVar = static_cast<VariableExprAST &>(*LHS);
- // Codegen the RHS.
- Value *Val = RHS->IRGen(C);
- if (!Val) return nullptr;
-
- // Look up the name.
- if (auto Variable = C.NamedValues[LHSVar.Name]) {
- C.getBuilder().CreateStore(Val, Variable);
- return Val;
- }
- return ErrorP<Value>("Unknown variable name");
- }
-
- Value *L = LHS->IRGen(C);
- Value *R = RHS->IRGen(C);
- if (!L || !R) return nullptr;
-
- switch (Op) {
- case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp");
- case '-': return C.getBuilder().CreateFSub(L, R, "subtmp");
- case '*': return C.getBuilder().CreateFMul(L, R, "multmp");
- case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp");
- case '<':
- L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp");
- // Convert bool 0/1 to double 0.0 or 1.0
- return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
- "booltmp");
- default: break;
- }
-
- // If it wasn't a builtin binary operator, it must be a user defined one. Emit
- // a call to it.
- std::string FnName = MakeLegalFunctionName(std::string("binary")+Op);
- if (Function *F = C.getPrototype(FnName)) {
- Value *Ops[] = { L, R };
- return C.getBuilder().CreateCall(F, Ops, "binop");
- }
-
- return ErrorP<Value>("Unknown binary operator");
-}
-
-Value *CallExprAST::IRGen(IRGenContext &C) const {
- // Look up the name in the global module table.
- if (auto CalleeF = C.getPrototype(CalleeName)) {
- // If argument mismatch error.
- if (CalleeF->arg_size() != Args.size())
- return ErrorP<Value>("Incorrect # arguments passed");
-
- std::vector<Value*> ArgsV;
- for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- ArgsV.push_back(Args[i]->IRGen(C));
- if (!ArgsV.back()) return nullptr;
- }
-
- return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp");
- }
-
- return ErrorP<Value>("Unknown function referenced");
-}
-
-Value *IfExprAST::IRGen(IRGenContext &C) const {
- Value *CondV = Cond->IRGen(C);
- if (!CondV) return nullptr;
-
- // Convert condition to a bool by comparing equal to 0.0.
- ConstantFP *FPZero =
- ConstantFP::get(C.getLLVMContext(), APFloat(0.0));
- CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond");
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create blocks for the then and else cases. Insert the 'then' block at the
- // end of the function.
- BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont");
-
- C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB);
-
- // Emit then value.
- C.getBuilder().SetInsertPoint(ThenBB);
-
- Value *ThenV = Then->IRGen(C);
- if (!ThenV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
- ThenBB = C.getBuilder().GetInsertBlock();
-
- // Emit else block.
- TheFunction->getBasicBlockList().push_back(ElseBB);
- C.getBuilder().SetInsertPoint(ElseBB);
-
- Value *ElseV = Else->IRGen(C);
- if (!ElseV) return nullptr;
-
- C.getBuilder().CreateBr(MergeBB);
- // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
- ElseBB = C.getBuilder().GetInsertBlock();
-
- // Emit merge block.
- TheFunction->getBasicBlockList().push_back(MergeBB);
- C.getBuilder().SetInsertPoint(MergeBB);
- PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
- "iftmp");
-
- PN->addIncoming(ThenV, ThenBB);
- PN->addIncoming(ElseV, ElseBB);
- return PN;
-}
-
-Value *ForExprAST::IRGen(IRGenContext &C) const {
- // Output this as:
- // var = alloca double
- // ...
- // start = startexpr
- // store start -> var
- // goto loop
- // loop:
- // ...
- // bodyexpr
- // ...
- // loopend:
- // step = stepexpr
- // endcond = endexpr
- //
- // curvar = load var
- // nextvar = curvar + step
- // store nextvar -> var
- // br endcond, loop, endloop
- // outloop:
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Create an alloca for the variable in the entry block.
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
-
- // Emit the start code first, without 'variable' in scope.
- Value *StartVal = Start->IRGen(C);
- if (!StartVal) return nullptr;
-
- // Store the value into the alloca.
- C.getBuilder().CreateStore(StartVal, Alloca);
-
- // Make the new basic block for the loop header, inserting after current
- // block.
- BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
-
- // Insert an explicit fall through from the current block to the LoopBB.
- C.getBuilder().CreateBr(LoopBB);
-
- // Start insertion in LoopBB.
- C.getBuilder().SetInsertPoint(LoopBB);
-
- // Within the loop, the variable is defined equal to the PHI node. If it
- // shadows an existing variable, we have to restore it, so save it now.
- AllocaInst *OldVal = C.NamedValues[VarName];
- C.NamedValues[VarName] = Alloca;
-
- // Emit the body of the loop. This, like any other expr, can change the
- // current BB. Note that we ignore the value computed by the body, but don't
- // allow an error.
- if (!Body->IRGen(C))
- return nullptr;
-
- // Emit the step value.
- Value *StepVal;
- if (Step) {
- StepVal = Step->IRGen(C);
- if (!StepVal) return nullptr;
- } else {
- // If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
- }
-
- // Compute the end condition.
- Value *EndCond = End->IRGen(C);
- if (!EndCond) return nullptr;
-
- // Reload, increment, and restore the alloca. This handles the case where
- // the body of the loop mutates the variable.
- Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str());
- Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar");
- C.getBuilder().CreateStore(NextVar, Alloca);
-
- // Convert condition to a bool by comparing equal to 0.0.
- EndCond = C.getBuilder().CreateFCmpONE(EndCond,
- ConstantFP::get(getGlobalContext(), APFloat(0.0)),
- "loopcond");
-
- // Create the "after loop" block and insert it.
- BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
-
- // Insert the conditional branch into the end of LoopEndBB.
- C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB);
-
- // Any new code will be inserted in AfterBB.
- C.getBuilder().SetInsertPoint(AfterBB);
-
- // Restore the unshadowed variable.
- if (OldVal)
- C.NamedValues[VarName] = OldVal;
- else
- C.NamedValues.erase(VarName);
-
- // for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
-}
-
-Value *VarExprAST::IRGen(IRGenContext &C) const {
- std::vector<AllocaInst *> OldBindings;
-
- Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();
-
- // Register all variables and emit their initializer.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) {
- auto &VarName = VarBindings[i].first;
- auto &Init = VarBindings[i].second;
-
- // Emit the initializer before adding the variable to scope, this prevents
- // the initializer from referencing the variable itself, and permits stuff
- // like this:
- // var a = 1 in
- // var a = a in ... # refers to outer 'a'.
- Value *InitVal;
- if (Init) {
- InitVal = Init->IRGen(C);
- if (!InitVal) return nullptr;
- } else // If not specified, use 0.0.
- InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
-
- AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- C.getBuilder().CreateStore(InitVal, Alloca);
-
- // Remember the old variable binding so that we can restore the binding when
- // we unrecurse.
- OldBindings.push_back(C.NamedValues[VarName]);
-
- // Remember this binding.
- C.NamedValues[VarName] = Alloca;
- }
-
- // Codegen the body, now that all vars are in scope.
- Value *BodyVal = Body->IRGen(C);
- if (!BodyVal) return nullptr;
-
- // Pop all our variables from scope.
- for (unsigned i = 0, e = VarBindings.size(); i != e; ++i)
- C.NamedValues[VarBindings[i].first] = OldBindings[i];
-
- // Return the body computation.
- return BodyVal;
-}
-
-Function *PrototypeAST::IRGen(IRGenContext &C) const {
- std::string FnName = MakeLegalFunctionName(Name);
-
- // Make the function type: double(double,double) etc.
- std::vector<Type*> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
- FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
- Doubles, false);
- Function *F = Function::Create(FT, Function::ExternalLinkage, FnName,
- &C.getM());
-
- // If F conflicted, there was already something named 'FnName'. If it has a
- // body, don't allow redefinition or reextern.
- if (F->getName() != FnName) {
- // Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = C.getM().getFunction(Name);
-
- // If F already has a body, reject this.
- if (!F->empty()) {
- ErrorP<Function>("redefinition of function");
- return nullptr;
- }
-
- // If F took a different number of args, reject.
- if (F->arg_size() != Args.size()) {
- ErrorP<Function>("redefinition of function with different # args");
- return nullptr;
- }
- }
-
- // Set names for all arguments.
- unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
- ++AI, ++Idx)
- AI->setName(Args[Idx]);
-
- return F;
-}
-
-/// CreateArgumentAllocas - Create an alloca for each argument and register the
-/// argument in the symbol table so that references to it will succeed.
-void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) {
- Function::arg_iterator AI = F->arg_begin();
- for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
- // Create an alloca for this variable.
- AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
-
- // Store the initial value into the alloca.
- C.getBuilder().CreateStore(&*AI, Alloca);
-
- // Add arguments to variable symbol table.
- C.NamedValues[Args[Idx]] = Alloca;
- }
-}
-
-Function *FunctionAST::IRGen(IRGenContext &C) const {
- C.NamedValues.clear();
-
- Function *TheFunction = Proto->IRGen(C);
- if (!TheFunction)
- return nullptr;
-
- // If this is an operator, install it.
- if (Proto->isBinaryOp())
- BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence;
-
- // Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
- C.getBuilder().SetInsertPoint(BB);
-
- // Add all arguments to the symbol table and create their allocas.
- Proto->CreateArgumentAllocas(TheFunction, C);
-
- if (Value *RetVal = Body->IRGen(C)) {
- // Finish off the function.
- C.getBuilder().CreateRet(RetVal);
-
- // Validate the generated code, checking for consistency.
- verifyFunction(*TheFunction);
-
- return TheFunction;
- }
-
- // Error reading body, remove function.
- TheFunction->eraseFromParent();
-
- if (Proto->isBinaryOp())
- BinopPrecedence.erase(Proto->getOperatorName());
- return nullptr;
-}
-
-//===----------------------------------------------------------------------===//
-// Top-Level parsing and JIT Driver
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<llvm::Module> IRGen(SessionContext &S,
- const FunctionAST &F) {
- IRGenContext C(S);
- auto LF = F.IRGen(C);
- if (!LF)
- return nullptr;
-#ifndef MINIMAL_STDERR_OUTPUT
- fprintf(stderr, "Read function definition:");
- LF->dump();
-#endif
- return C.takeM();
-}
-
-template <typename T>
-static std::vector<T> singletonSet(T t) {
- std::vector<T> Vec;
- Vec.push_back(std::move(t));
- return Vec;
-}
-
-class KaleidoscopeJIT {
-public:
- typedef ObjectLinkingLayer<> ObjLayerT;
- typedef IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
- typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT;
-
- KaleidoscopeJIT(SessionContext &Session)
- : Session(Session),
- CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())),
- LazyEmitLayer(CompileLayer) {}
-
- std::string mangle(const std::string &Name) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name,
- Session.getTarget().createDataLayout());
- }
- return MangledName;
- }
-
- void addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
- std::cerr << "Adding AST: " << FnAST->Proto->Name << "\n";
- FunctionDefs[mangle(FnAST->Proto->Name)] = std::move(FnAST);
- }
-
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- // We need a memory manager to allocate memory and resolve symbols for this
- // new module. Create one that resolves symbols by looking back into the
- // JIT.
- auto Resolver = createLambdaResolver(
- [&](const std::string &Name) {
- // First try to find 'Name' within the JIT.
- if (auto Symbol = findSymbol(Name))
- return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
- Symbol.getFlags());
-
- // If we don't already have a definition of 'Name' then search
- // the ASTs.
- return searchFunctionASTs(Name);
- },
- [](const std::string &S) { return nullptr; } );
-
- return LazyEmitLayer.addModuleSet(singletonSet(std::move(M)),
- make_unique<SectionMemoryManager>(),
- std::move(Resolver));
- }
-
- void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
-
- JITSymbol findSymbol(const std::string &Name) {
- return LazyEmitLayer.findSymbol(Name, true);
- }
-
- JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
- return LazyEmitLayer.findSymbolIn(H, Name, true);
- }
-
- JITSymbol findUnmangledSymbol(const std::string &Name) {
- return findSymbol(mangle(Name));
- }
-
-private:
-
- // This method searches the FunctionDefs map for a definition of 'Name'. If it
- // finds one it generates a stub for it and returns the address of the stub.
- RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) {
- auto DefI = FunctionDefs.find(Name);
- if (DefI == FunctionDefs.end())
- return nullptr;
-
- // Take the FunctionAST out of the map.
- auto FnAST = std::move(DefI->second);
- FunctionDefs.erase(DefI);
-
- // IRGen the AST, add it to the JIT, and return the address for it.
- auto H = addModule(IRGen(Session, *FnAST));
- auto Sym = findSymbolIn(H, Name);
- return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
- }
-
- SessionContext &Session;
- ObjLayerT ObjectLayer;
- CompileLayerT CompileLayer;
- LazyEmitLayerT LazyEmitLayer;
-
- std::map<std::string, std::unique_ptr<FunctionAST>> FunctionDefs;
-};
-
-static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) {
- if (auto F = ParseDefinition()) {
- S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto));
- J.addFunctionAST(std::move(F));
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleExtern(SessionContext &S) {
- if (auto P = ParseExtern())
- S.addPrototypeAST(std::move(P));
- else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {
- // Evaluate a top-level expression into an anonymous function.
- if (auto F = ParseTopLevelExpr()) {
- IRGenContext C(S);
- if (auto ExprFunc = F->IRGen(C)) {
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "Expression function:\n";
- ExprFunc->dump();
-#endif
- // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove
- // this module as soon as we've executed Function ExprFunc.
- auto H = J.addModule(C.takeM());
-
- // Get the address of the JIT'd function in memory.
- auto ExprSymbol = J.findUnmangledSymbol("__anon_expr");
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
- double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
-#ifdef MINIMAL_STDERR_OUTPUT
- FP();
-#else
- std::cerr << "Evaluated to " << FP() << "\n";
-#endif
-
- // Remove the function.
- J.removeModule(H);
- }
- } else {
- // Skip token for error recovery.
- getNextToken();
- }
-}
-
-/// top ::= definition | external | expression | ';'
-static void MainLoop() {
- SessionContext S(getGlobalContext());
- KaleidoscopeJIT J(S);
-
- while (1) {
- switch (CurTok) {
- case tok_eof: return;
- case ';': getNextToken(); continue; // ignore top-level semicolons.
- case tok_def: HandleDefinition(S, J); break;
- case tok_extern: HandleExtern(S); break;
- default: HandleTopLevelExpression(S, J); break;
- }
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- }
-}
-
-//===----------------------------------------------------------------------===//
-// "Library" functions that can be "extern'd" from user code.
-//===----------------------------------------------------------------------===//
-
-/// putchard - putchar that takes a double and returns 0.
-extern "C"
-double putchard(double X) {
- putchar((char)X);
- return 0;
-}
-
-/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C"
-double printd(double X) {
- printf("%f", X);
- return 0;
-}
-
-extern "C"
-double printlf() {
- printf("\n");
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// Main driver code.
-//===----------------------------------------------------------------------===//
-
-int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
- // Install standard binary operators.
- // 1 is lowest precedence.
- BinopPrecedence['='] = 2;
- BinopPrecedence['<'] = 10;
- BinopPrecedence['+'] = 20;
- BinopPrecedence['-'] = 20;
- BinopPrecedence['/'] = 40;
- BinopPrecedence['*'] = 40; // highest.
-
- // Prime the first token.
-#ifndef MINIMAL_STDERR_OUTPUT
- std::cerr << "ready> ";
-#endif
- getNextToken();
-
- std::cerr << std::fixed;
-
- // Run the main "interpreter loop" now.
- MainLoop();
-
- return 0;
-}
diff --git a/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/examples/Kaleidoscope/include/KaleidoscopeJIT.h
index 0c825cc94c0e1..2f492b0e17ffd 100644
--- a/examples/Kaleidoscope/include/KaleidoscopeJIT.h
+++ b/examples/Kaleidoscope/include/KaleidoscopeJIT.h
@@ -14,14 +14,27 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/JITSymbolFlags.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
namespace llvm {
namespace orc {
@@ -47,7 +60,7 @@ public:
auto Resolver = createLambdaResolver(
[&](const std::string &Name) {
if (auto Sym = findMangledSymbol(Name))
- return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ return Sym.toRuntimeDyldSymbol();
return RuntimeDyld::SymbolInfo(nullptr);
},
[](const std::string &S) { return nullptr; });
@@ -70,7 +83,6 @@ public:
}
private:
-
std::string mangle(const std::string &Name) {
std::string MangledName;
{
@@ -108,7 +120,7 @@ private:
std::vector<ModuleHandleT> ModuleHandles;
};
-} // End namespace orc.
-} // End namespace llvm
+} // end namespace orc
+} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
diff --git a/examples/Makefile b/examples/Makefile
deleted file mode 100644
index 50a6db76aa255..0000000000000
--- a/examples/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-##===- examples/Makefile -----------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL=..
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS:= BrainF Fibonacci HowToUseJIT Kaleidoscope ModuleMaker
-
-ifeq ($(HAVE_PTHREAD),1)
-PARALLEL_DIRS += ParallelJIT
-endif
-
-ifeq ($(LLVM_ON_UNIX),1)
- ifeq ($(ARCH),x86)
- PARALLEL_DIRS += ExceptionDemo
- endif
- ifeq ($(ARCH),x86_64)
- PARALLEL_DIRS += ExceptionDemo
- endif
-endif
-
-ifeq ($(filter $(BINDINGS_TO_BUILD),ocaml),ocaml)
- PARALLEL_DIRS += OCaml-Kaleidoscope
-endif
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/ModuleMaker/Makefile b/examples/ModuleMaker/Makefile
deleted file mode 100644
index 9454cf514dc14..0000000000000
--- a/examples/ModuleMaker/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- examples/ModuleMaker/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL=../..
-TOOLNAME=ModuleMaker
-EXAMPLE_TOOL = 1
-LINK_COMPONENTS := bitwriter
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/ModuleMaker/ModuleMaker.cpp b/examples/ModuleMaker/ModuleMaker.cpp
index c931972f5b60d..d6f998b39225c 100644
--- a/examples/ModuleMaker/ModuleMaker.cpp
+++ b/examples/ModuleMaker/ModuleMaker.cpp
@@ -14,12 +14,18 @@
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
int main() {
diff --git a/examples/OCaml-Kaleidoscope/Chapter2/Makefile b/examples/OCaml-Kaleidoscope/Chapter2/Makefile
deleted file mode 100644
index 8fc03da0fbd43..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter2/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter2/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 2.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch2
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm
-
-OCAMLCFLAGS += -pp camlp4of
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Chapter3/Makefile b/examples/OCaml-Kaleidoscope/Chapter3/Makefile
deleted file mode 100644
index fdbcd5191f401..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter3/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter3/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 3.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch3
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm llvm_analysis
-
-OCAMLCFLAGS += -pp camlp4of
-
-ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Chapter4/Makefile b/examples/OCaml-Kaleidoscope/Chapter4/Makefile
deleted file mode 100644
index d9c3f49bea6e3..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter4/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter4/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 4.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch4
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
- llvm_scalar_opts
-
-OCAMLCFLAGS += -pp camlp4of
-
-ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Chapter5/Makefile b/examples/OCaml-Kaleidoscope/Chapter5/Makefile
deleted file mode 100644
index f31c10d3c2fb2..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter5/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter5/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 5.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch5
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
- llvm_scalar_opts
-
-OCAMLCFLAGS += -pp camlp4of
-
-ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Chapter6/Makefile b/examples/OCaml-Kaleidoscope/Chapter6/Makefile
deleted file mode 100644
index 21f0c53df4b9d..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter6/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter6/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 6.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch6
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
- llvm_scalar_opts
-
-OCAMLCFLAGS += -pp camlp4of
-
-OcamlSources1 = \
- $(PROJ_SRC_DIR)/ast.ml \
- $(PROJ_SRC_DIR)/parser.ml \
- $(PROJ_SRC_DIR)/codegen.ml \
- $(PROJ_SRC_DIR)/lexer.ml \
- $(PROJ_SRC_DIR)/token.ml \
- $(PROJ_SRC_DIR)/toplevel.ml \
- $(PROJ_SRC_DIR)/toy.ml
-
-ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Chapter7/Makefile b/examples/OCaml-Kaleidoscope/Chapter7/Makefile
deleted file mode 100644
index 99686e17ea80d..0000000000000
--- a/examples/OCaml-Kaleidoscope/Chapter7/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Chapter7/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This is the makefile for the Objective Caml kaleidoscope tutorial, chapter 7.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL := ../../..
-TOOLNAME := OCaml-Kaleidoscope-Ch7
-EXAMPLE_TOOL := 1
-UsedComponents := core
-UsedOcamLibs := llvm llvm_analysis llvm_executionengine llvm_target \
- llvm_scalar_opts
-
-OCAMLCFLAGS += -pp camlp4of
-
-OcamlSources1 = \
- $(PROJ_SRC_DIR)/ast.ml \
- $(PROJ_SRC_DIR)/parser.ml \
- $(PROJ_SRC_DIR)/codegen.ml \
- $(PROJ_SRC_DIR)/lexer.ml \
- $(PROJ_SRC_DIR)/token.ml \
- $(PROJ_SRC_DIR)/toplevel.ml \
- $(PROJ_SRC_DIR)/toy.ml
-
-ExcludeSources = $(PROJ_SRC_DIR)/myocamlbuild.ml
-
-include $(LEVEL)/bindings/ocaml/Makefile.ocaml
diff --git a/examples/OCaml-Kaleidoscope/Makefile b/examples/OCaml-Kaleidoscope/Makefile
deleted file mode 100644
index 5342b94022a9e..0000000000000
--- a/examples/OCaml-Kaleidoscope/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- examples/OCaml-Kaleidoscope/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL=../..
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS:= Chapter2 Chapter3 Chapter4 Chapter5 Chapter6 Chapter7
-
-include $(LEVEL)/Makefile.common
diff --git a/examples/ParallelJIT/CMakeLists.txt b/examples/ParallelJIT/CMakeLists.txt
index 07c0a085b91f6..e85b470f5036b 100644
--- a/examples/ParallelJIT/CMakeLists.txt
+++ b/examples/ParallelJIT/CMakeLists.txt
@@ -11,6 +11,4 @@ add_llvm_example(ParallelJIT
ParallelJIT.cpp
)
-if(HAVE_LIBPTHREAD)
- target_link_libraries(ParallelJIT pthread)
-endif(HAVE_LIBPTHREAD)
+target_link_libraries(ParallelJIT ${PTHREAD_LIB})
diff --git a/examples/ParallelJIT/Makefile b/examples/ParallelJIT/Makefile
deleted file mode 100644
index 0f2a3575f76c7..0000000000000
--- a/examples/ParallelJIT/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- examples/ParallelJIT/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-TOOLNAME = ParallelJIT
-EXAMPLE_TOOL = 1
-
-LINK_COMPONENTS := mcjit interpreter nativecodegen
-
-include $(LEVEL)/Makefile.common
-
-LIBS += -lpthread
diff --git a/examples/ParallelJIT/ParallelJIT.cpp b/examples/ParallelJIT/ParallelJIT.cpp
index 3c485d4c964d1..6fb8bd61982b5 100644
--- a/examples/ParallelJIT/ParallelJIT.cpp
+++ b/examples/ParallelJIT/ParallelJIT.cpp
@@ -16,17 +16,33 @@
// wakes them up. This complicated work is performed so that all three threads
// call into the JIT at the same time (or the best possible approximation of the
// same time). This test had assertion errors until I got the locking right.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/TargetSelect.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <iostream>
+#include <memory>
+#include <vector>
#include <pthread.h>
using namespace llvm;