llvm.org GIT mirror llvm / 203f697
[Kaleidoscope][BuildingAJIT] Add code for Chapter 5 - remote JITing. This chapter demonstrates lazily JITing from ASTs with the expressions being executed on a remote machine via a TCP connection. It needs some polish, but is substantially complete. Currently x86-64 SysV ABI (Darwin and Linux) only, but other architectures can be supported by changing the server code to use alternative ABI support classes from llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271193 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 3 years ago
7 changed file(s) with 1789 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
11 add_subdirectory(Chapter2)
22 add_subdirectory(Chapter3)
33 add_subdirectory(Chapter4)
4 add_subdirectory(Chapter5)
45
0 add_subdirectory(Server)
1
2 set(LLVM_LINK_COMPONENTS
3 Analysis
4 Core
5 ExecutionEngine
6 InstCombine
7 Object
8 OrcJIT
9 RuntimeDyld
10 ScalarOpts
11 Support
12 TransformUtils
13 native
14 )
15
16 add_kaleidoscope_chapter(BuildingAJIT-Ch5
17 toy.cpp
18 )
19
20 export_executable_symbols(BuildingAJIT-Ch5)
0 //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Contains a simple JIT definition for use in the kaleidoscope tutorials.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
14 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
15
16 #include "RemoteJITUtils.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ExecutionEngine/ExecutionEngine.h"
19 #include "llvm/ExecutionEngine/RuntimeDyld.h"
20 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
21 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
22 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
23 #include "llvm/ExecutionEngine/Orc/JITSymbol.h"
24 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
25 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
26 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
27 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
28 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
29 #include "llvm/IR/DataLayout.h"
30 #include "llvm/IR/Mangler.h"
31 #include "llvm/Support/DynamicLibrary.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetMachine.h"
34 #include
35 #include
36 #include
37 #include
38
39 class PrototypeAST;
40 class ExprAST;
41
42 /// FunctionAST - This class represents a function definition itself.
43 class FunctionAST {
44 std::unique_ptr Proto;
45 std::unique_ptr Body;
46
47 public:
48 FunctionAST(std::unique_ptr Proto,
49 std::unique_ptr Body)
50 : Proto(std::move(Proto)), Body(std::move(Body)) {}
51 const PrototypeAST& getProto() const;
52 const std::string& getName() const;
53 llvm::Function *codegen();
54 };
55
56 /// This will compile FnAST to IR, rename the function to add the given
57 /// suffix (needed to prevent a name-clash with the function's stub),
58 /// and then take ownership of the module that the function was compiled
59 /// into.
60 std::unique_ptr
61 irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix);
62
63 namespace llvm {
64 namespace orc {
65
66 // Typedef the remote-client API.
67 typedef remote::OrcRemoteTargetClient MyRemote;
68
69 class KaleidoscopeJIT {
70 private:
71 MyRemote &Remote;
72 std::unique_ptr TM;
73 const DataLayout DL;
74 JITCompileCallbackManager *CompileCallbackMgr;
75 std::unique_ptr IndirectStubsMgr;
76 ObjectLinkingLayer<> ObjectLayer;
77 IRCompileLayer CompileLayer;
78
79 typedef std::function(std::unique_ptr)>
80 OptimizeFunction;
81
82 IRTransformLayer OptimizeLayer;
83
84 public:
85 typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
86
87 KaleidoscopeJIT(MyRemote &Remote)
88 : Remote(Remote),
89 TM(EngineBuilder().selectTarget()),
90 DL(TM->createDataLayout()),
91 CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
92 OptimizeLayer(CompileLayer,
93 [this](std::unique_ptr M) {
94 return optimizeModule(std::move(M));
95 }) {
96 auto CCMgrOrErr = Remote.enableCompileCallbacks(0);
97 if (!CCMgrOrErr) {
98 logAllUnhandledErrors(CCMgrOrErr.takeError(), errs(),
99 "Error enabling remote compile callbacks:");
100 exit(1);
101 }
102 CompileCallbackMgr = &*CCMgrOrErr;
103 std::unique_ptr ISM;
104 if (auto Err = Remote.createIndirectStubsManager(ISM)) {
105 logAllUnhandledErrors(std::move(Err), errs(),
106 "Error creating indirect stubs manager:");
107 exit(1);
108 }
109 IndirectStubsMgr = std::move(ISM);
110 llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
111 }
112
113 TargetMachine &getTargetMachine() { return *TM; }
114
115 ModuleHandle addModule(std::unique_ptr M) {
116
117 // Build our symbol resolver:
118 // Lambda 1: Look back into the JIT itself to find symbols that are part of
119 // the same "logical dylib".
120 // Lambda 2: Search for external symbols in the host process.
121 auto Resolver = createLambdaResolver(
122 [&](const std::string &Name) {
123 if (auto Sym = IndirectStubsMgr->findStub(Name, false))
124 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
125 if (auto Sym = OptimizeLayer.findSymbol(Name, false))
126 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
127 return RuntimeDyld::SymbolInfo(nullptr);
128 },
129 [&](const std::string &Name) {
130 if (auto AddrOrErr = Remote.getSymbolAddress(Name))
131 return RuntimeDyld::SymbolInfo(*AddrOrErr,
132 JITSymbolFlags::Exported);
133 else {
134 logAllUnhandledErrors(AddrOrErr.takeError(), errs(),
135 "Error resolving remote symbol:");
136 exit(1);
137 }
138 return RuntimeDyld::SymbolInfo(nullptr);
139 });
140
141 std::unique_ptr MemMgr;
142 if (auto Err = Remote.createRemoteMemoryManager(MemMgr)) {
143 logAllUnhandledErrors(std::move(Err), errs(),
144 "Error creating remote memory manager:");
145 exit(1);
146 }
147
148 // Build a singlton module set to hold our module.
149 std::vector> Ms;
150 Ms.push_back(std::move(M));
151
152 // Add the set to the JIT with the resolver we created above and a newly
153 // created SectionMemoryManager.
154 return OptimizeLayer.addModuleSet(std::move(Ms),
155 std::move(MemMgr),
156 std::move(Resolver));
157 }
158
159 Error addFunctionAST(std::unique_ptr FnAST) {
160 // Create a CompileCallback - this is the re-entry point into the compiler
161 // for functions that haven't been compiled yet.
162 auto CCInfo = CompileCallbackMgr->getCompileCallback();
163
164 // Create an indirect stub. This serves as the functions "canonical
165 // definition" - an unchanging (constant address) entry point to the
166 // function implementation.
167 // Initially we point the stub's function-pointer at the compile callback
168 // that we just created. In the compile action for the callback (see below)
169 // we will update the stub's function pointer to point at the function
170 // implementation that we just implemented.
171 if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()),
172 CCInfo.getAddress(),
173 JITSymbolFlags::Exported))
174 return Err;
175
176 // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support
177 // capture-by-move, which is be required for unique_ptr.
178 auto SharedFnAST = std::shared_ptr(std::move(FnAST));
179
180 // Set the action to compile our AST. This lambda will be run if/when
181 // execution hits the compile callback (via the stub).
182 //
183 // The steps to compile are:
184 // (1) IRGen the function.
185 // (2) Add the IR module to the JIT to make it executable like any other
186 // module.
187 // (3) Use findSymbol to get the address of the compiled function.
188 // (4) Update the stub pointer to point at the implementation so that
189 /// subsequent calls go directly to it and bypass the compiler.
190 // (5) Return the address of the implementation: this lambda will actually
191 // be run inside an attempted call to the function, and we need to
192 // continue on to the implementation to complete the attempted call.
193 // The JIT runtime (the resolver block) will use the return address of
194 // this function as the address to continue at once it has reset the
195 // CPU state to what it was immediately before the call.
196 CCInfo.setCompileAction(
197 [this, SharedFnAST]() {
198 auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl");
199 addModule(std::move(M));
200 auto Sym = findSymbol(SharedFnAST->getName() + "$impl");
201 assert(Sym && "Couldn't find compiled function?");
202 TargetAddress SymAddr = Sym.getAddress();
203 if (auto Err =
204 IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()),
205 SymAddr)) {
206 logAllUnhandledErrors(std::move(Err), errs(),
207 "Error updating function pointer: ");
208 exit(1);
209 }
210
211 return SymAddr;
212 });
213
214 return Error::success();
215 }
216
217 Error executeRemoteExpr(TargetAddress ExprAddr) {
218 return Remote.callVoidVoid(ExprAddr);
219 }
220
221 JITSymbol findSymbol(const std::string Name) {
222 return OptimizeLayer.findSymbol(mangle(Name), true);
223 }
224
225 void removeModule(ModuleHandle H) {
226 OptimizeLayer.removeModuleSet(H);
227 }
228
229 private:
230
231 std::string mangle(const std::string &Name) {
232 std::string MangledName;
233 raw_string_ostream MangledNameStream(MangledName);
234 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
235 return MangledNameStream.str();
236 }
237
238 std::unique_ptr optimizeModule(std::unique_ptr M) {
239 // Create a function pass manager.
240 auto FPM = llvm::make_unique(M.get());
241
242 // Add some optimizations.
243 FPM->add(createInstructionCombiningPass());
244 FPM->add(createReassociatePass());
245 FPM->add(createGVNPass());
246 FPM->add(createCFGSimplificationPass());
247 FPM->doInitialization();
248
249 // Run the optimizations over all functions in the module being added to
250 // the JIT.
251 for (auto &F : *M)
252 FPM->run(F);
253
254 return M;
255 }
256
257 };
258
259 } // end namespace orc
260 } // end namespace llvm
261
262 #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
0 //===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Utilities for remote-JITing with LLI.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H
14 #define LLVM_TOOLS_LLI_REMOTEJITUTILS_H
15
16 #include "llvm/ExecutionEngine/Orc/RPCChannel.h"
17 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
18 #include
19
20 #if !defined(_MSC_VER) && !defined(__MINGW32__)
21 #include
22 #else
23 #include
24 #endif
25
26 /// RPC channel that reads from and writes from file descriptors.
27 class FDRPCChannel final : public llvm::orc::remote::RPCChannel {
28 public:
29 FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
30
31 llvm::Error readBytes(char *Dst, unsigned Size) override {
32 assert(Dst && "Attempt to read into null.");
33 ssize_t Completed = 0;
34 while (Completed < static_cast(Size)) {
35 ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);
36 if (Read <= 0) {
37 auto ErrNo = errno;
38 if (ErrNo == EAGAIN || ErrNo == EINTR)
39 continue;
40 else
41 return llvm::errorCodeToError(
42 std::error_code(errno, std::generic_category()));
43 }
44 Completed += Read;
45 }
46 return llvm::Error::success();
47 }
48
49 llvm::Error appendBytes(const char *Src, unsigned Size) override {
50 assert(Src && "Attempt to append from null.");
51 ssize_t Completed = 0;
52 while (Completed < static_cast(Size)) {
53 ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);
54 if (Written < 0) {
55 auto ErrNo = errno;
56 if (ErrNo == EAGAIN || ErrNo == EINTR)
57 continue;
58 else
59 return llvm::errorCodeToError(
60 std::error_code(errno, std::generic_category()));
61 }
62 Completed += Written;
63 }
64 return llvm::Error::success();
65 }
66
67 llvm::Error send() override { return llvm::Error::success(); }
68
69 private:
70 int InFD, OutFD;
71 };
72
73 #endif
0 set(LLVM_LINK_COMPONENTS
1 Analysis
2 Core
3 ExecutionEngine
4 InstCombine
5 Object
6 OrcJIT
7 RuntimeDyld
8 ScalarOpts
9 Support
10 TransformUtils
11 native
12 )
13
14 add_kaleidoscope_chapter(BuildingAJIT-Ch5-Server
15 server.cpp
16 )
0 #include "llvm/Support/CommandLine.h"
1 #include "llvm/Support/DynamicLibrary.h"
2 #include "llvm/Support/TargetSelect.h"
3 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"
4 #include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
5
6 #include "../RemoteJITUtils.h"
7
8 #include
9 #include
10 #include
11 #include
12
13
14 using namespace llvm;
15 using namespace llvm::orc;
16
17 // Command line argument for TCP port.
18 cl::opt Port("port",
19 cl::desc("TCP port to listen on"),
20 cl::init(20000));
21
22 ExitOnError ExitOnErr;
23
24 typedef int (*MainFun)(int, const char*[]);
25
26 template
27 NativePtrT MakeNative(uint64_t P) {
28 return reinterpret_cast(static_cast(P));
29 }
30
31 extern "C"
32 void printExprResult(double Val) {
33 printf("Expression evaluated to: %f\n", Val);
34 }
35
36 // --- LAZY COMPILE TEST ---
37 int main(int argc, char* argv[]) {
38
39 if (argc == 0)
40 ExitOnErr.setBanner("jit_server: ");
41 else
42 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
43
44 // --- Initialize LLVM ---
45 cl::ParseCommandLineOptions(argc, argv, "LLVM lazy JIT example.\n");
46
47 InitializeNativeTarget();
48 InitializeNativeTargetAsmPrinter();
49 InitializeNativeTargetAsmParser();
50
51 if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
52 errs() << "Error loading program symbols.\n";
53 return 1;
54 }
55
56 // --- Initialize remote connection ---
57
58 int sockfd = socket(PF_INET, SOCK_STREAM, 0);
59 sockaddr_in servAddr, clientAddr;
60 socklen_t clientAddrLen = sizeof(clientAddr);
61 bzero(&servAddr, sizeof(servAddr));
62 servAddr.sin_family = PF_INET;
63 servAddr.sin_family = INADDR_ANY;
64 servAddr.sin_port = htons(Port);
65
66 {
67 // avoid "Address already in use" error.
68 int yes=1;
69 if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
70 errs() << "Error calling setsockopt.\n";
71 return 1;
72 }
73 }
74
75 if (bind(sockfd, reinterpret_cast(&servAddr),
76 sizeof(servAddr)) < 0) {
77 errs() << "Error on binding.\n";
78 return 1;
79 }
80 listen(sockfd, 1);
81 int newsockfd = accept(sockfd, reinterpret_cast(&clientAddr),
82 &clientAddrLen);
83
84 auto SymbolLookup =
85 [](const std::string &Name) {
86 return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
87 };
88
89 auto RegisterEHFrames =
90 [](uint8_t *Addr, uint32_t Size) {
91 RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size);
92 };
93
94 auto DeregisterEHFrames =
95 [](uint8_t *Addr, uint32_t Size) {
96 RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size);
97 };
98
99 FDRPCChannel TCPChannel(newsockfd, newsockfd);
100 typedef remote::OrcRemoteTargetServer MyServerT;
101
102 MyServerT Server(TCPChannel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames);
103
104 while (1) {
105 MyServerT::JITFuncId Id = MyServerT::InvalidId;
106 ExitOnErr(Server.startReceivingFunction(TCPChannel, (uint32_t&)Id));
107 switch (Id) {
108 case MyServerT::TerminateSessionId:
109 ExitOnErr(Server.handleTerminateSession());
110 return 0;
111 default:
112 ExitOnErr(Server.handleKnownFunction(Id));
113 break;
114 }
115 }
116
117 llvm_unreachable("Fell through server command loop.");
118 }
0 #include "llvm/ADT/APFloat.h"
1 #include "llvm/ADT/STLExtras.h"
2 #include "llvm/IR/BasicBlock.h"
3 #include "llvm/IR/Constants.h"
4 #include "llvm/IR/DerivedTypes.h"
5 #include "llvm/IR/Function.h"
6 #include "llvm/IR/Instructions.h"
7 #include "llvm/IR/IRBuilder.h"
8 #include "llvm/IR/LLVMContext.h"
9 #include "llvm/IR/LegacyPassManager.h"
10 #include "llvm/IR/Module.h"
11 #include "llvm/IR/Type.h"
12 #include "llvm/IR/Verifier.h"
13 #include "llvm/Support/Error.h"
14 #include "llvm/Support/TargetSelect.h"
15 #include "llvm/Target/TargetMachine.h"
16 #include "llvm/Transforms/Scalar.h"
17 #include "llvm/Transforms/Scalar/GVN.h"
18 #include "KaleidoscopeJIT.h"
19 #include
20 #include
21 #include
22 #include
23 #include
24 #include
25 #include
26 #include
27 #include
28 #include
29
30 #include
31 #include
32 #include
33 #include
34
35 using namespace llvm;
36 using namespace llvm::orc;
37
38 // Command line argument for TCP hostname.
39 cl::opt HostName("hostname",
40 cl::desc("TCP hostname to connect to"),
41 cl::init("localhost"));
42
43 // Command line argument for TCP port.
44 cl::opt Port("port",
45 cl::desc("TCP port to connect to"),
46 cl::init(20000));
47
48 //===----------------------------------------------------------------------===//
49 // Lexer
50 //===----------------------------------------------------------------------===//
51
52 // The lexer returns tokens [0-255] if it is an unknown character, otherwise one
53 // of these for known things.
54 enum Token {
55 tok_eof = -1,
56
57 // commands
58 tok_def = -2,
59 tok_extern = -3,
60
61 // primary
62 tok_identifier = -4,
63 tok_number = -5,
64
65 // control
66 tok_if = -6,
67 tok_then = -7,
68 tok_else = -8,
69 tok_for = -9,
70 tok_in = -10,
71
72 // operators
73 tok_binary = -11,
74 tok_unary = -12,
75
76 // var definition
77 tok_var = -13
78 };
79
80 static std::string IdentifierStr; // Filled in if tok_identifier
81 static double NumVal; // Filled in if tok_number
82
83 /// gettok - Return the next token from standard input.
84 static int gettok() {
85 static int LastChar = ' ';
86
87 // Skip any whitespace.
88 while (isspace(LastChar))
89 LastChar = getchar();
90
91 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
92 IdentifierStr = LastChar;
93 while (isalnum((LastChar = getchar())))
94 IdentifierStr += LastChar;
95
96 if (IdentifierStr == "def")
97 return tok_def;
98 if (IdentifierStr == "extern")
99 return tok_extern;
100 if (IdentifierStr == "if")
101 return tok_if;
102 if (IdentifierStr == "then")
103 return tok_then;
104 if (IdentifierStr == "else")
105 return tok_else;
106 if (IdentifierStr == "for")
107 return tok_for;
108 if (IdentifierStr == "in")
109 return tok_in;
110 if (IdentifierStr == "binary")
111 return tok_binary;
112 if (IdentifierStr == "unary")
113 return tok_unary;
114 if (IdentifierStr == "var")
115 return tok_var;
116 return tok_identifier;
117 }
118
119 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
120 std::string NumStr;
121 do {
122 NumStr += LastChar;
123 LastChar = getchar();
124 } while (isdigit(LastChar) || LastChar == '.');
125
126 NumVal = strtod(NumStr.c_str(), nullptr);
127 return tok_number;
128 }
129
130 if (LastChar == '#') {
131 // Comment until end of line.
132 do
133 LastChar = getchar();
134 while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
135
136 if (LastChar != EOF)
137 return gettok();
138 }
139
140 // Check for end of file. Don't eat the EOF.
141 if (LastChar == EOF)
142 return tok_eof;
143
144 // Otherwise, just return the character as its ascii value.
145 int ThisChar = LastChar;
146 LastChar = getchar();
147 return ThisChar;
148 }
149
150 //===----------------------------------------------------------------------===//
151 // Abstract Syntax Tree (aka Parse Tree)
152 //===----------------------------------------------------------------------===//
153
154 /// ExprAST - Base class for all expression nodes.
155 class ExprAST {
156 public:
157 virtual ~ExprAST() {}
158 virtual Value *codegen() = 0;
159 };
160
161 /// NumberExprAST - Expression class for numeric literals like "1.0".
162 class NumberExprAST : public ExprAST {
163 double Val;
164
165 public:
166 NumberExprAST(double Val) : Val(Val) {}
167 Value *codegen() override;
168 };
169
170 /// VariableExprAST - Expression class for referencing a variable, like "a".
171 class VariableExprAST : public ExprAST {
172 std::string Name;
173
174 public:
175 VariableExprAST(const std::string &Name) : Name(Name) {}
176 const std::string &getName() const { return Name; }
177 Value *codegen() override;
178 };
179
180 /// UnaryExprAST - Expression class for a unary operator.
181 class UnaryExprAST : public ExprAST {
182 char Opcode;
183 std::unique_ptr Operand;
184
185 public:
186 UnaryExprAST(char Opcode, std::unique_ptr Operand)
187 : Opcode(Opcode), Operand(std::move(Operand)) {}
188 Value *codegen() override;
189 };
190
191 /// BinaryExprAST - Expression class for a binary operator.
192 class BinaryExprAST : public ExprAST {
193 char Op;
194 std::unique_ptr LHS, RHS;
195
196 public:
197 BinaryExprAST(char Op, std::unique_ptr LHS,
198 std::unique_ptr RHS)
199 : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
200 Value *codegen() override;
201 };
202
203 /// CallExprAST - Expression class for function calls.
204 class CallExprAST : public ExprAST {
205 std::string Callee;
206 std::vector> Args;
207
208 public:
209 CallExprAST(const std::string &Callee,
210 std::vector> Args)
211 : Callee(Callee), Args(std::move(Args)) {}
212 Value *codegen() override;
213 };
214
215 /// IfExprAST - Expression class for if/then/else.
216 class IfExprAST : public ExprAST {
217 std::unique_ptr Cond, Then, Else;
218
219 public:
220 IfExprAST(std::unique_ptr Cond, std::unique_ptr Then,
221 std::unique_ptr Else)
222 : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
223 Value *codegen() override;
224 };
225
226 /// ForExprAST - Expression class for for/in.
227 class ForExprAST : public ExprAST {
228 std::string VarName;
229 std::unique_ptr Start, End, Step, Body;
230
231 public:
232 ForExprAST(const std::string &VarName, std::unique_ptr Start,
233 std::unique_ptr End, std::unique_ptr Step,
234 std::unique_ptr Body)
235 : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
236 Step(std::move(Step)), Body(std::move(Body)) {}
237 Value *codegen() override;
238 };
239
240 /// VarExprAST - Expression class for var/in
241 class VarExprAST : public ExprAST {
242 std::vector>> VarNames;
243 std::unique_ptr Body;
244
245 public:
246 VarExprAST(
247 std::vector>> VarNames,
248 std::unique_ptr Body)
249 : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
250 Value *codegen() override;
251 };
252
253 /// PrototypeAST - This class represents the "prototype" for a function,
254 /// which captures its name, and its argument names (thus implicitly the number
255 /// of arguments the function takes), as well as if it is an operator.
256 class PrototypeAST {
257 std::string Name;
258 std::vector Args;
259 bool IsOperator;
260 unsigned Precedence; // Precedence if a binary op.
261
262 public:
263 PrototypeAST(const std::string &Name, std::vector Args,
264 bool IsOperator = false, unsigned Prec = 0)
265 : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
266 Precedence(Prec) {}
267 Function *codegen();
268 const std::string &getName() const { return Name; }
269
270 bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
271 bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
272
273 char getOperatorName() const {
274 assert(isUnaryOp() || isBinaryOp());
275 return Name[Name.size() - 1];
276 }
277
278 unsigned getBinaryPrecedence() const { return Precedence; }
279 };
280
281 //===----------------------------------------------------------------------===//
282 // Parser
283 //===----------------------------------------------------------------------===//
284
285 /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
286 /// token the parser is looking at. getNextToken reads another token from the
287 /// lexer and updates CurTok with its results.
288 static int CurTok;
289 static int getNextToken() { return CurTok = gettok(); }
290
291 /// BinopPrecedence - This holds the precedence for each binary operator that is
292 /// defined.
293 static std::map BinopPrecedence;
294
295 /// GetTokPrecedence - Get the precedence of the pending binary operator token.
296 static int GetTokPrecedence() {
297 if (!isascii(CurTok))
298 return -1;
299
300 // Make sure it's a declared binop.
301 int TokPrec = BinopPrecedence[CurTok];
302 if (TokPrec <= 0)
303 return -1;
304 return TokPrec;
305 }
306
307 /// LogError* - These are little helper functions for error handling.
308 std::unique_ptr LogError(const char *Str) {
309 fprintf(stderr, "Error: %s\n", Str);
310 return nullptr;
311 }
312
313 std::unique_ptr LogErrorP(const char *Str) {
314 LogError(Str);
315 return nullptr;
316 }
317
318 static std::unique_ptr ParseExpression();
319
320 /// numberexpr ::= number
321 static std::unique_ptr ParseNumberExpr() {
322 auto Result = llvm::make_unique(NumVal);
323 getNextToken(); // consume the number
324 return std::move(Result);
325 }
326
327 /// parenexpr ::= '(' expression ')'
328 static std::unique_ptr ParseParenExpr() {
329 getNextToken(); // eat (.
330 auto V = ParseExpression();
331 if (!V)
332 return nullptr;
333
334 if (CurTok != ')')
335 return LogError("expected ')'");
336 getNextToken(); // eat ).
337 return V;
338 }
339
340 /// identifierexpr
341 /// ::= identifier
342 /// ::= identifier '(' expression* ')'
343 static std::unique_ptr ParseIdentifierExpr() {
344 std::string IdName = IdentifierStr;
345
346 getNextToken(); // eat identifier.
347
348 if (CurTok != '(') // Simple variable ref.
349 return llvm::make_unique(IdName);
350
351 // Call.
352 getNextToken(); // eat (
353 std::vector> Args;
354 if (CurTok != ')') {
355 while (true) {
356 if (auto Arg = ParseExpression())
357 Args.push_back(std::move(Arg));
358 else
359 return nullptr;
360
361 if (CurTok == ')')
362 break;
363
364 if (CurTok != ',')
365 return LogError("Expected ')' or ',' in argument list");
366 getNextToken();
367 }
368 }
369
370 // Eat the ')'.
371 getNextToken();
372
373 return llvm::make_unique(IdName, std::move(Args));
374 }
375
376 /// ifexpr ::= 'if' expression 'then' expression 'else' expression
377 static std::unique_ptr ParseIfExpr() {
378 getNextToken(); // eat the if.
379
380 // condition.
381 auto Cond = ParseExpression();
382 if (!Cond)
383 return nullptr;
384
385 if (CurTok != tok_then)
386 return LogError("expected then");
387 getNextToken(); // eat the then
388
389 auto Then = ParseExpression();
390 if (!Then)
391 return nullptr;
392
393 if (CurTok != tok_else)
394 return LogError("expected else");
395
396 getNextToken();
397
398 auto Else = ParseExpression();
399 if (!Else)
400 return nullptr;
401
402 return llvm::make_unique(std::move(Cond), std::move(Then),
403 std::move(Else));
404 }
405
406 /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
407 static std::unique_ptr ParseForExpr() {
408 getNextToken(); // eat the for.
409
410 if (CurTok != tok_identifier)
411 return LogError("expected identifier after for");
412
413 std::string IdName = IdentifierStr;
414 getNextToken(); // eat identifier.
415
416 if (CurTok != '=')
417 return LogError("expected '=' after for");
418 getNextToken(); // eat '='.
419
420 auto Start = ParseExpression();
421 if (!Start)
422 return nullptr;
423 if (CurTok != ',')
424 return LogError("expected ',' after for start value");
425 getNextToken();
426
427 auto End = ParseExpression();
428 if (!End)
429 return nullptr;
430
431 // The step value is optional.
432 std::unique_ptr Step;
433 if (CurTok == ',') {
434 getNextToken();
435 Step = ParseExpression();
436 if (!Step)
437 return nullptr;
438 }
439
440 if (CurTok != tok_in)
441 return LogError("expected 'in' after for");
442 getNextToken(); // eat 'in'.
443
444 auto Body = ParseExpression();
445 if (!Body)
446 return nullptr;
447
448 return llvm::make_unique(IdName, std::move(Start), std::move(End),
449 std::move(Step), std::move(Body));
450 }
451
452 /// varexpr ::= 'var' identifier ('=' expression)?
453 // (',' identifier ('=' expression)?)* 'in' expression
454 static std::unique_ptr ParseVarExpr() {
455 getNextToken(); // eat the var.
456
457 std::vector>> VarNames;
458
459 // At least one variable name is required.
460 if (CurTok != tok_identifier)
461 return LogError("expected identifier after var");
462
463 while (true) {
464 std::string Name = IdentifierStr;
465 getNextToken(); // eat identifier.
466
467 // Read the optional initializer.
468 std::unique_ptr Init = nullptr;
469 if (CurTok == '=') {
470 getNextToken(); // eat the '='.
471
472 Init = ParseExpression();
473 if (!Init)
474 return nullptr;
475 }
476
477 VarNames.push_back(std::make_pair(Name, std::move(Init)));
478
479 // End of var list, exit loop.
480 if (CurTok != ',')
481 break;
482 getNextToken(); // eat the ','.
483
484 if (CurTok != tok_identifier)
485 return LogError("expected identifier list after var");
486 }
487
488 // At this point, we have to have 'in'.
489 if (CurTok != tok_in)
490 return LogError("expected 'in' keyword after 'var'");
491 getNextToken(); // eat 'in'.
492
493 auto Body = ParseExpression();
494 if (!Body)
495 return nullptr;
496
497 return llvm::make_unique(std::move(VarNames), std::move(Body));
498 }
499
500 /// primary
501 /// ::= identifierexpr
502 /// ::= numberexpr
503 /// ::= parenexpr
504 /// ::= ifexpr
505 /// ::= forexpr
506 /// ::= varexpr
507 static std::unique_ptr ParsePrimary() {
508 switch (CurTok) {
509 default:
510 return LogError("unknown token when expecting an expression");
511 case tok_identifier:
512 return ParseIdentifierExpr();
513 case tok_number:
514 return ParseNumberExpr();
515 case '(':
516 return ParseParenExpr();
517 case tok_if:
518 return ParseIfExpr();
519 case tok_for:
520 return ParseForExpr();
521 case tok_var:
522 return ParseVarExpr();
523 }
524 }
525
526 /// unary
527 /// ::= primary
528 /// ::= '!' unary
529 static std::unique_ptr ParseUnary() {
530 // If the current token is not an operator, it must be a primary expr.
531 if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
532 return ParsePrimary();
533
534 // If this is a unary operator, read it.
535 int Opc = CurTok;
536 getNextToken();
537 if (auto Operand = ParseUnary())
538 return llvm::make_unique(Opc, std::move(Operand));
539 return nullptr;
540 }
541
542 /// binoprhs
543 /// ::= ('+' unary)*
544 static std::unique_ptr ParseBinOpRHS(int ExprPrec,
545 std::unique_ptr LHS) {
546 // If this is a binop, find its precedence.
547 while (true) {
548 int TokPrec = GetTokPrecedence();
549
550 // If this is a binop that binds at least as tightly as the current binop,
551 // consume it, otherwise we are done.
552 if (TokPrec < ExprPrec)
553 return LHS;
554
555 // Okay, we know this is a binop.
556 int BinOp = CurTok;
557 getNextToken(); // eat binop
558
559 // Parse the unary expression after the binary operator.
560 auto RHS = ParseUnary();
561 if (!RHS)
562 return nullptr;
563
564 // If BinOp binds less tightly with RHS than the operator after RHS, let
565 // the pending operator take RHS as its LHS.
566 int NextPrec = GetTokPrecedence();
567 if (TokPrec < NextPrec) {
568 RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
569 if (!RHS)
570 return nullptr;
571 }
572
573 // Merge LHS/RHS.
574 LHS =
575 llvm::make_unique(BinOp, std::move(LHS), std::move(RHS));
576 }
577 }
578
579 /// expression
580 /// ::= unary binoprhs
581 ///
582 static std::unique_ptr ParseExpression() {
583 auto LHS = ParseUnary();
584 if (!LHS)
585 return nullptr;
586
587 return ParseBinOpRHS(0, std::move(LHS));
588 }
589
590 /// prototype
591 /// ::= id '(' id* ')'
592 /// ::= binary LETTER number? (id, id)
593 /// ::= unary LETTER (id)
594 static std::unique_ptr ParsePrototype() {
595 std::string FnName;
596
597 unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
598 unsigned BinaryPrecedence = 30;
599
600 switch (CurTok) {
601 default:
602 return LogErrorP("Expected function name in prototype");
603 case tok_identifier:
604 FnName = IdentifierStr;
605 Kind = 0;
606 getNextToken();
607 break;
608 case tok_unary:
609 getNextToken();
610 if (!isascii(CurTok))
611 return LogErrorP("Expected unary operator");
612 FnName = "unary";
613 FnName += (char)CurTok;
614 Kind = 1;
615 getNextToken();
616 break;
617 case tok_binary:
618 getNextToken();
619 if (!isascii(CurTok))
620 return LogErrorP("Expected binary operator");
621 FnName = "binary";
622 FnName += (char)CurTok;
623 Kind = 2;
624 getNextToken();
625
626 // Read the precedence if present.
627 if (CurTok == tok_number) {
628 if (NumVal < 1 || NumVal > 100)
629 return LogErrorP("Invalid precedecnce: must be 1..100");
630 BinaryPrecedence = (unsigned)NumVal;
631 getNextToken();
632 }
633 break;
634 }
635
636 if (CurTok != '(')
637 return LogErrorP("Expected '(' in prototype");
638
639 std::vector ArgNames;
640 while (getNextToken() == tok_identifier)
641 ArgNames.push_back(IdentifierStr);
642 if (CurTok != ')')
643 return LogErrorP("Expected ')' in prototype");
644
645 // success.
646 getNextToken(); // eat ')'.
647
648 // Verify right number of names for operator.
649 if (Kind && ArgNames.size() != Kind)
650 return LogErrorP("Invalid number of operands for operator");
651
652 return llvm::make_unique(FnName, ArgNames, Kind != 0,
653 BinaryPrecedence);
654 }
655
656 /// definition ::= 'def' prototype expression
657 static std::unique_ptr ParseDefinition() {
658 getNextToken(); // eat def.
659 auto Proto = ParsePrototype();
660 if (!Proto)
661 return nullptr;
662
663 if (auto E = ParseExpression())
664 return llvm::make_unique(std::move(Proto), std::move(E));
665 return nullptr;
666 }
667
668 /// toplevelexpr ::= expression
669 static std::unique_ptr ParseTopLevelExpr() {
670 if (auto E = ParseExpression()) {
671
672 auto PEArgs = std::vector>();
673 PEArgs.push_back(std::move(E));
674 auto PrintExpr =
675 llvm::make_unique("printExprResult", std::move(PEArgs));
676
677 // Make an anonymous proto.
678 auto Proto = llvm::make_unique("__anon_expr",
679 std::vector());
680 return llvm::make_unique(std::move(Proto),
681 std::move(PrintExpr));
682 }
683 return nullptr;
684 }
685
686 /// external ::= 'extern' prototype
687 static std::unique_ptr ParseExtern() {
688 getNextToken(); // eat extern.
689 return ParsePrototype();
690 }
691
692 //===----------------------------------------------------------------------===//
693 // Code Generation
694 //===----------------------------------------------------------------------===//
695
696 static LLVMContext TheContext;
697 static IRBuilder<> Builder(TheContext);
698 static std::unique_ptr TheModule;
699 static std::map NamedValues;
700 static std::unique_ptr TheJIT;
701 static std::map> FunctionProtos;
702 static ExitOnError ExitOnErr;
703
704 Value *LogErrorV(const char *Str) {
705 LogError(Str);
706 return nullptr;
707 }
708
709 Function *getFunction(std::string Name) {
710 // First, see if the function has already been added to the current module.
711 if (auto *F = TheModule->getFunction(Name))
712 return F;
713
714 // If not, check whether we can codegen the declaration from some existing
715 // prototype.
716 auto FI = FunctionProtos.find(Name);
717 if (FI != FunctionProtos.end())
718 return FI->second->codegen();
719
720 // If no existing prototype exists, return null.
721 return nullptr;
722 }
723
724 /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
725 /// the function. This is used for mutable variables etc.
726 static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
727 const std::string &VarName) {
728 IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
729 TheFunction->getEntryBlock().begin());
730 return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
731 }
732
733 Value *NumberExprAST::codegen() {
734 return ConstantFP::get(TheContext, APFloat(Val));
735 }
736
737 Value *VariableExprAST::codegen() {
738 // Look this variable up in the function.
739 Value *V = NamedValues[Name];
740 if (!V)
741 return LogErrorV("Unknown variable name");
742
743 // Load the value.
744 return Builder.CreateLoad(V, Name.c_str());
745 }
746
747 Value *UnaryExprAST::codegen() {
748 Value *OperandV = Operand->codegen();
749 if (!OperandV)
750 return nullptr;
751
752 Function *F = getFunction(std::string("unary") + Opcode);
753 if (!F)
754 return LogErrorV("Unknown unary operator");
755
756 return Builder.CreateCall(F, OperandV, "unop");
757 }
758
759 Value *BinaryExprAST::codegen() {
760 // Special case '=' because we don't want to emit the LHS as an expression.
761 if (Op == '=') {
762 // Assignment requires the LHS to be an identifier.
763 // This assume we're building without RTTI because LLVM builds that way by
764 // default. If you build LLVM with RTTI this can be changed to a
765 // dynamic_cast for automatic error checking.
766 VariableExprAST *LHSE = static_cast(LHS.get());
767 if (!LHSE)
768 return LogErrorV("destination of '=' must be a variable");
769 // Codegen the RHS.
770 Value *Val = RHS->codegen();
771 if (!Val)
772 return nullptr;
773
774 // Look up the name.
775 Value *Variable = NamedValues[LHSE->getName()];
776 if (!Variable)
777 return LogErrorV("Unknown variable name");
778
779 Builder.CreateStore(Val, Variable);
780 return Val;
781 }
782
783 Value *L = LHS->codegen();
784 Value *R = RHS->codegen();
785 if (!L || !R)
786 return nullptr;
787
788 switch (Op) {
789 case '+':
790 return Builder.CreateFAdd(L, R, "addtmp");
791 case '-':
792 return Builder.CreateFSub(L, R, "subtmp");
793 case '*':
794 return Builder.CreateFMul(L, R, "multmp");
795 case '<':
796 L = Builder.CreateFCmpULT(L, R, "cmptmp");
797 // Convert bool 0/1 to double 0.0 or 1.0
798 return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
799 default:
800 break;
801 }
802
803 // If it wasn't a builtin binary operator, it must be a user defined one. Emit
804 // a call to it.
805 Function *F = getFunction(std::string("binary") + Op);
806 assert(F && "binary operator not found!");
807
808 Value *Ops[] = {L, R};
809 return Builder.CreateCall(F, Ops, "binop");
810 }
811
812 Value *CallExprAST::codegen() {
813 // Look up the name in the global module table.
814 Function *CalleeF = getFunction(Callee);
815 if (!CalleeF)
816 return LogErrorV("Unknown function referenced");
817
818 // If argument mismatch error.
819 if (CalleeF->arg_size() != Args.size())
820 return LogErrorV("Incorrect # arguments passed");
821
822 std::vector ArgsV;
823 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
824 ArgsV.push_back(Args[i]->codegen());
825 if (!ArgsV.back())
826 return nullptr;
827 }
828
829 return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
830 }
831
832 Value *IfExprAST::codegen() {
833 Value *CondV = Cond->codegen();
834 if (!CondV)
835 return nullptr;
836
837 // Convert condition to a bool by comparing equal to 0.0.
838 CondV = Builder.CreateFCmpONE(
839 CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
840
841 Function *TheFunction = Builder.GetInsertBlock()->getParent();
842
843 // Create blocks for the then and else cases. Insert the 'then' block at the
844 // end of the function.
845 BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
846 BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
847 BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
848
849 Builder.CreateCondBr(CondV, ThenBB, ElseBB);
850
851 // Emit then value.
852 Builder.SetInsertPoint(ThenBB);
853
854 Value *ThenV = Then->codegen();
855 if (!ThenV)
856 return nullptr;
857
858 Builder.CreateBr(MergeBB);
859 // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
860 ThenBB = Builder.GetInsertBlock();
861
862 // Emit else block.
863 TheFunction->getBasicBlockList().push_back(ElseBB);
864 Builder.SetInsertPoint(ElseBB);
865
866 Value *ElseV = Else->codegen();
867 if (!ElseV)
868 return nullptr;
869
870 Builder.CreateBr(MergeBB);
871 // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
872 ElseBB = Builder.GetInsertBlock();
873
874 // Emit merge block.
875 TheFunction->getBasicBlockList().push_back(MergeBB);
876 Builder.SetInsertPoint(MergeBB);
877 PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
878
879 PN->addIncoming(ThenV, ThenBB);
880 PN->addIncoming(ElseV, ElseBB);
881 return PN;
882 }
883
884 // Output for-loop as:
885 // var = alloca double
886 // ...
887 // start = startexpr
888 // store start -> var
889 // goto loop
890 // loop:
891 // ...
892 // bodyexpr
893 // ...
894 // loopend:
895 // step = stepexpr
896 // endcond = endexpr
897 //
898 // curvar = load var
899 // nextvar = curvar + step
900 // store nextvar -> var
901 // br endcond, loop, endloop
902 // outloop:
903 Value *ForExprAST::codegen() {
904 Function *TheFunction = Builder.GetInsertBlock()->getParent();
905
906 // Create an alloca for the variable in the entry block.
907 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
908
909 // Emit the start code first, without 'variable' in scope.
910 Value *StartVal = Start->codegen();
911 if (!StartVal)
912 return nullptr;
913
914 // Store the value into the alloca.
915 Builder.CreateStore(StartVal, Alloca);
916
917 // Make the new basic block for the loop header, inserting after current
918 // block.
919 BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
920
921 // Insert an explicit fall through from the current block to the LoopBB.
922 Builder.CreateBr(LoopBB);
923
924 // Start insertion in LoopBB.
925 Builder.SetInsertPoint(LoopBB);
926
927 // Within the loop, the variable is defined equal to the PHI node. If it
928 // shadows an existing variable, we have to restore it, so save it now.
929 AllocaInst *OldVal = NamedValues[VarName];
930 NamedValues[VarName] = Alloca;
931
932 // Emit the body of the loop. This, like any other expr, can change the
933 // current BB. Note that we ignore the value computed by the body, but don't
934 // allow an error.
935 if (!Body->codegen())
936 return nullptr;
937
938 // Emit the step value.
939 Value *StepVal = nullptr;
940 if (Step) {
941 StepVal = Step->codegen();
942 if (!StepVal)
943 return nullptr;
944 } else {
945 // If not specified, use 1.0.
946 StepVal = ConstantFP::get(TheContext, APFloat(1.0));
947 }
948
949 // Compute the end condition.
950 Value *EndCond = End->codegen();
951 if (!EndCond)
952 return nullptr;
953
954 // Reload, increment, and restore the alloca. This handles the case where
955 // the body of the loop mutates the variable.
956 Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
957 Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
958 Builder.CreateStore(NextVar, Alloca);
959
960 // Convert condition to a bool by comparing equal to 0.0.
961 EndCond = Builder.CreateFCmpONE(
962 EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
963
964 // Create the "after loop" block and insert it.
965 BasicBlock *AfterBB =
966 BasicBlock::Create(TheContext, "afterloop", TheFunction);
967
968 // Insert the conditional branch into the end of LoopEndBB.
969 Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
970
971 // Any new code will be inserted in AfterBB.
972 Builder.SetInsertPoint(AfterBB);
973
974 // Restore the unshadowed variable.
975 if (OldVal)
976 NamedValues[VarName] = OldVal;
977 else
978 NamedValues.erase(VarName);
979
980 // for expr always returns 0.0.
981 return Constant::getNullValue(Type::getDoubleTy(TheContext));
982 }
983
984 Value *VarExprAST::codegen() {
985 std::vector OldBindings;
986
987 Function *TheFunction = Builder.GetInsertBlock()->getParent();
988
989 // Register all variables and emit their initializer.
990 for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
991 const std::string &VarName = VarNames[i].first;
992 ExprAST *Init = VarNames[i].second.get();
993
994 // Emit the initializer before adding the variable to scope, this prevents
995 // the initializer from referencing the variable itself, and permits stuff
996 // like this:
997 // var a = 1 in
998 // var a = a in ... # refers to outer 'a'.
999 Value *InitVal;
1000 if (Init) {
1001 InitVal = Init->codegen();
1002 if (!InitVal)
1003 return nullptr;
1004 } else { // If not specified, use 0.0.
1005 InitVal = ConstantFP::get(TheContext, APFloat(0.0));
1006 }
1007
1008 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
1009 Builder.CreateStore(InitVal, Alloca);
1010
1011 // Remember the old variable binding so that we can restore the binding when
1012 // we unrecurse.
1013 OldBindings.push_back(NamedValues[VarName]);
1014
1015 // Remember this binding.
1016 NamedValues[VarName] = Alloca;
1017 }
1018
1019 // Codegen the body, now that all vars are in scope.
1020 Value *BodyVal = Body->codegen();
1021 if (!BodyVal)
1022 return nullptr;
1023
1024 // Pop all our variables from scope.
1025 for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
1026 NamedValues[VarNames[i].first] = OldBindings[i];
1027
1028 // Return the body computation.
1029 return BodyVal;
1030 }
1031
1032 Function *PrototypeAST::codegen() {
1033 // Make the function type: double(double,double) etc.
1034 std::vector Doubles(Args.size(), Type::getDoubleTy(TheContext));
1035 FunctionType *FT =
1036 FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
1037
1038 Function *F =
1039 Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
1040
1041 // Set names for all arguments.
1042 unsigned Idx = 0;
1043 for (auto &Arg : F->args())
1044 Arg.setName(Args[Idx++]);
1045
1046 return F;
1047 }
1048
1049 const PrototypeAST& FunctionAST::getProto() const {
1050 return *Proto;
1051 }
1052
1053 const std::string& FunctionAST::getName() const {
1054 return Proto->getName();
1055 }
1056
1057 Function *FunctionAST::codegen() {
1058 // Transfer ownership of the prototype to the FunctionProtos map, but keep a
1059 // reference to it for use below.
1060 auto &P = *Proto;
1061 Function *TheFunction = getFunction(P.getName());
1062 if (!TheFunction)
1063 return nullptr;
1064
1065 // If this is an operator, install it.
1066 if (P.isBinaryOp())
1067 BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
1068
1069 // Create a new basic block to start insertion into.
1070 BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
1071 Builder.SetInsertPoint(BB);
1072
1073 // Record the function arguments in the NamedValues map.
1074 NamedValues.clear();
1075 for (auto &Arg : TheFunction->args()) {
1076 // Create an alloca for this variable.
1077 AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
1078
1079 // Store the initial value into the alloca.
1080 Builder.CreateStore(&Arg, Alloca);
1081
1082 // Add arguments to variable symbol table.
1083 NamedValues[Arg.getName()] = Alloca;
1084 }
1085
1086 if (Value *RetVal = Body->codegen()) {
1087 // Finish off the function.
1088 Builder.CreateRet(RetVal);
1089
1090 // Validate the generated code, checking for consistency.
1091 verifyFunction(*TheFunction);
1092
1093 return TheFunction;
1094 }
1095
1096 // Error reading body, remove function.
1097 TheFunction->eraseFromParent();
1098
1099 if (P.isBinaryOp())
1100 BinopPrecedence.erase(Proto->getOperatorName());
1101 return nullptr;
1102 }
1103
1104 //===----------------------------------------------------------------------===//
1105 // Top-Level parsing and JIT Driver
1106 //===----------------------------------------------------------------------===//
1107
1108 static void InitializeModule() {
1109 // Open a new module.
1110 TheModule = llvm::make_unique("my cool jit", TheContext);
1111 TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
1112 }
1113
1114 std::unique_ptr
1115 irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix) {
1116 if (auto *F = FnAST.codegen()) {
1117 F->setName(F->getName() + Suffix);
1118 auto M = std::move(TheModule);
1119 // Start a new module.
1120 InitializeModule();
1121 return M;
1122 } else
1123 report_fatal_error("Couldn't compile lazily JIT'd function");
1124 }
1125
1126 static void HandleDefinition() {
1127 if (auto FnAST = ParseDefinition()) {
1128 FunctionProtos[FnAST->getProto().getName()] =
1129 llvm::make_unique(FnAST->getProto());
1130 ExitOnErr(TheJIT->addFunctionAST(std::move(FnAST)));
1131 } else {
1132 // Skip token for error recovery.
1133 getNextToken();
1134 }
1135 }
1136
1137 static void HandleExtern() {
1138 if (auto ProtoAST = ParseExtern()) {
1139 if (auto *FnIR = ProtoAST->codegen()) {
1140 fprintf(stderr, "Read extern: ");
1141 FnIR->dump();
1142 FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
1143 }
1144 } else {
1145 // Skip token for error recovery.
1146 getNextToken();
1147 }
1148 }
1149
1150 static void HandleTopLevelExpression() {
1151 // Evaluate a top-level expression into an anonymous function.
1152 if (auto FnAST = ParseTopLevelExpr()) {
1153 FunctionProtos[FnAST->getName()] =
1154 llvm::make_unique(FnAST->getProto());
1155 if (FnAST->codegen()) {
1156 // JIT the module containing the anonymous expression, keeping a handle so
1157 // we can free it later.
1158 auto H = TheJIT->addModule(std::move(TheModule));
1159 InitializeModule();
1160
1161 // Search the JIT for the __anon_expr symbol.
1162 auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
1163 assert(ExprSymbol && "Function not found");
1164
1165 // Get the symbol's address and cast it to the right type (takes no
1166 // arguments, returns a double) so we can call it as a native function.
1167 ExitOnErr(TheJIT->executeRemoteExpr(ExprSymbol.getAddress()));
1168
1169 // Delete the anonymous expression module from the JIT.
1170 TheJIT->removeModule(H);
1171 }
1172 } else {
1173 // Skip token for error recovery.
1174 getNextToken();
1175 }
1176 }
1177
1178 /// top ::= definition | external | expression | ';'
1179 static void MainLoop() {
1180 while (true) {
1181 fprintf(stderr, "ready> ");
1182 switch (CurTok) {
1183 case tok_eof:
1184 return;
1185 case ';': // ignore top-level semicolons.
1186 getNextToken();
1187 break;
1188 case tok_def:
1189 HandleDefinition();
1190 break;
1191 case tok_extern:
1192 HandleExtern();
1193 break;
1194 default:
1195 HandleTopLevelExpression();
1196 break;
1197 }
1198 }
1199 }
1200
1201 //===----------------------------------------------------------------------===//
1202 // "Library" functions that can be "extern'd" from user code.
1203 //===----------------------------------------------------------------------===//
1204
1205 /// putchard - putchar that takes a double and returns 0.
1206 extern "C" double putchard(double X) {
1207 fputc((char)X, stderr);
1208 return 0;
1209 }
1210
1211 /// printd - printf that takes a double prints it as "%f\n", returning 0.
1212 extern "C" double printd(double X) {
1213 fprintf(stderr, "%f\n", X);
1214 return 0;
1215 }
1216
1217 //===----------------------------------------------------------------------===//
1218 // TCP / Connection setup code.
1219 //===----------------------------------------------------------------------===//
1220
1221 std::unique_ptr connect() {
1222 int sockfd = socket(PF_INET, SOCK_STREAM, 0);
1223 hostent *server = gethostbyname(HostName.c_str());
1224
1225 if (!server) {
1226 errs() << "Could not find host " << HostName << "\n";
1227 exit(1);
1228 }
1229
1230 sockaddr_in servAddr;
1231 bzero(&servAddr, sizeof(servAddr));
1232 servAddr.sin_family = PF_INET;
1233 bcopy(server->h_addr, &servAddr.sin_addr.s_addr, server->h_length);
1234 servAddr.sin_port = htons(Port);
1235 if (connect(sockfd, reinterpret_cast(&servAddr),
1236 sizeof(servAddr)) < 0) {
1237 errs() << "Failure to connect.\n";
1238 exit(1);
1239 }
1240
1241 return llvm::make_unique(sockfd, sockfd);
1242 }
1243
1244 //===----------------------------------------------------------------------===//
1245 // Main driver code.
1246 //===----------------------------------------------------------------------===//
1247
1248 int main(int argc, char *argv[]) {
1249 // Parse the command line options.
1250 cl::ParseCommandLineOptions(argc, argv, "Building A JIT - Client.\n");
1251
1252 InitializeNativeTarget();
1253 InitializeNativeTargetAsmPrinter();
1254 InitializeNativeTargetAsmParser();
1255
1256 ExitOnErr.setBanner("Kaleidoscope: ");
1257
1258 // Install standard binary operators.
1259 // 1 is lowest precedence.
1260 BinopPrecedence['='] = 2;
1261 BinopPrecedence['<'] = 10;
1262 BinopPrecedence['+'] = 20;
1263 BinopPrecedence['-'] = 20;
1264 BinopPrecedence['*'] = 40; // highest.
1265
1266 auto TCPChannel = connect();
1267 MyRemote Remote = ExitOnErr(MyRemote::Create(*TCPChannel));
1268 TheJIT = llvm::make_unique(Remote);
1269
1270 // Automatically inject a definition for 'printExprResult'.
1271 FunctionProtos["printExprResult"] =
1272 llvm::make_unique("printExprResult",
1273 std::vector({"Val"}));
1274
1275 // Prime the first token.
1276 fprintf(stderr, "ready> ");
1277 getNextToken();
1278
1279 InitializeModule();
1280
1281 // Run the main "interpreter loop" now.
1282 MainLoop();
1283
1284 // Delete the JIT before the Remote and Channel go out of scope, otherwise
1285 // we'll crash in the JIT destructor when it tries to release remote
1286 // resources over a channel that no longer exists.
1287 TheJIT = nullptr;
1288
1289 // Send a terminate message to the remote to tell it to exit cleanly.
1290 ExitOnErr(Remote.terminateSession());
1291
1292 return 0;
1293 }