| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1 | #include "llvm/Analysis/Passes.h" | 
|  | 2 | #include "llvm/ExecutionEngine/Orc/CompileUtils.h" | 
|  | 3 | #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" | 
|  | 4 | #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" | 
|  | 5 | #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" | 
|  | 6 | #include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h" | 
|  | 7 | #include "llvm/IR/DataLayout.h" | 
|  | 8 | #include "llvm/IR/DerivedTypes.h" | 
|  | 9 | #include "llvm/IR/IRBuilder.h" | 
|  | 10 | #include "llvm/IR/LegacyPassManager.h" | 
|  | 11 | #include "llvm/IR/LLVMContext.h" | 
|  | 12 | #include "llvm/IR/Module.h" | 
|  | 13 | #include "llvm/IR/Verifier.h" | 
|  | 14 | #include "llvm/Support/TargetSelect.h" | 
|  | 15 | #include "llvm/Transforms/Scalar.h" | 
|  | 16 | #include <cctype> | 
|  | 17 | #include <iomanip> | 
|  | 18 | #include <iostream> | 
|  | 19 | #include <map> | 
|  | 20 | #include <sstream> | 
|  | 21 | #include <string> | 
|  | 22 | #include <vector> | 
| Lang Hames | e738061 | 2015-02-21 20:44:36 +0000 | [diff] [blame] | 23 |  | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 24 | using namespace llvm; | 
| Lang Hames | e738061 | 2015-02-21 20:44:36 +0000 | [diff] [blame] | 25 | using namespace llvm::orc; | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 26 |  | 
|  | 27 | //===----------------------------------------------------------------------===// | 
|  | 28 | // Lexer | 
|  | 29 | //===----------------------------------------------------------------------===// | 
|  | 30 |  | 
|  | 31 | // The lexer returns tokens [0-255] if it is an unknown character, otherwise one | 
|  | 32 | // of these for known things. | 
|  | 33 | enum Token { | 
|  | 34 | tok_eof = -1, | 
|  | 35 |  | 
|  | 36 | // commands | 
|  | 37 | tok_def = -2, tok_extern = -3, | 
|  | 38 |  | 
|  | 39 | // primary | 
|  | 40 | tok_identifier = -4, tok_number = -5, | 
|  | 41 |  | 
|  | 42 | // control | 
|  | 43 | tok_if = -6, tok_then = -7, tok_else = -8, | 
|  | 44 | tok_for = -9, tok_in = -10, | 
|  | 45 |  | 
|  | 46 | // operators | 
|  | 47 | tok_binary = -11, tok_unary = -12, | 
|  | 48 |  | 
|  | 49 | // var definition | 
|  | 50 | tok_var = -13 | 
|  | 51 | }; | 
|  | 52 |  | 
|  | 53 | static std::string IdentifierStr;  // Filled in if tok_identifier | 
|  | 54 | static double NumVal;              // Filled in if tok_number | 
|  | 55 |  | 
|  | 56 | /// gettok - Return the next token from standard input. | 
|  | 57 | static int gettok() { | 
|  | 58 | static int LastChar = ' '; | 
|  | 59 |  | 
|  | 60 | // Skip any whitespace. | 
|  | 61 | while (isspace(LastChar)) | 
|  | 62 | LastChar = getchar(); | 
|  | 63 |  | 
|  | 64 | if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* | 
|  | 65 | IdentifierStr = LastChar; | 
|  | 66 | while (isalnum((LastChar = getchar()))) | 
|  | 67 | IdentifierStr += LastChar; | 
|  | 68 |  | 
|  | 69 | if (IdentifierStr == "def") return tok_def; | 
|  | 70 | if (IdentifierStr == "extern") return tok_extern; | 
|  | 71 | if (IdentifierStr == "if") return tok_if; | 
|  | 72 | if (IdentifierStr == "then") return tok_then; | 
|  | 73 | if (IdentifierStr == "else") return tok_else; | 
|  | 74 | if (IdentifierStr == "for") return tok_for; | 
|  | 75 | if (IdentifierStr == "in") return tok_in; | 
|  | 76 | if (IdentifierStr == "binary") return tok_binary; | 
|  | 77 | if (IdentifierStr == "unary") return tok_unary; | 
|  | 78 | if (IdentifierStr == "var") return tok_var; | 
|  | 79 | return tok_identifier; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+ | 
|  | 83 | std::string NumStr; | 
|  | 84 | do { | 
|  | 85 | NumStr += LastChar; | 
|  | 86 | LastChar = getchar(); | 
|  | 87 | } while (isdigit(LastChar) || LastChar == '.'); | 
|  | 88 |  | 
|  | 89 | NumVal = strtod(NumStr.c_str(), 0); | 
|  | 90 | return tok_number; | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | if (LastChar == '#') { | 
|  | 94 | // Comment until end of line. | 
|  | 95 | do LastChar = getchar(); | 
|  | 96 | while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); | 
|  | 97 |  | 
|  | 98 | if (LastChar != EOF) | 
|  | 99 | return gettok(); | 
|  | 100 | } | 
|  | 101 |  | 
|  | 102 | // Check for end of file.  Don't eat the EOF. | 
|  | 103 | if (LastChar == EOF) | 
|  | 104 | return tok_eof; | 
|  | 105 |  | 
|  | 106 | // Otherwise, just return the character as its ascii value. | 
|  | 107 | int ThisChar = LastChar; | 
|  | 108 | LastChar = getchar(); | 
|  | 109 | return ThisChar; | 
|  | 110 | } | 
|  | 111 |  | 
|  | 112 | //===----------------------------------------------------------------------===// | 
|  | 113 | // Abstract Syntax Tree (aka Parse Tree) | 
|  | 114 | //===----------------------------------------------------------------------===// | 
|  | 115 |  | 
|  | 116 | class IRGenContext; | 
|  | 117 |  | 
|  | 118 | /// ExprAST - Base class for all expression nodes. | 
|  | 119 | struct ExprAST { | 
|  | 120 | virtual ~ExprAST() {} | 
|  | 121 | virtual Value *IRGen(IRGenContext &C) const = 0; | 
|  | 122 | }; | 
|  | 123 |  | 
|  | 124 | /// NumberExprAST - Expression class for numeric literals like "1.0". | 
|  | 125 | struct NumberExprAST : public ExprAST { | 
|  | 126 | NumberExprAST(double Val) : Val(Val) {} | 
|  | 127 | Value *IRGen(IRGenContext &C) const override; | 
|  | 128 |  | 
|  | 129 | double Val; | 
|  | 130 | }; | 
|  | 131 |  | 
|  | 132 | /// VariableExprAST - Expression class for referencing a variable, like "a". | 
|  | 133 | struct VariableExprAST : public ExprAST { | 
|  | 134 | VariableExprAST(std::string Name) : Name(std::move(Name)) {} | 
|  | 135 | Value *IRGen(IRGenContext &C) const override; | 
|  | 136 |  | 
|  | 137 | std::string Name; | 
|  | 138 | }; | 
|  | 139 |  | 
|  | 140 | /// UnaryExprAST - Expression class for a unary operator. | 
|  | 141 | struct UnaryExprAST : public ExprAST { | 
|  | 142 | UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) | 
|  | 143 | : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {} | 
|  | 144 |  | 
|  | 145 | Value *IRGen(IRGenContext &C) const override; | 
|  | 146 |  | 
|  | 147 | char Opcode; | 
|  | 148 | std::unique_ptr<ExprAST> Operand; | 
|  | 149 | }; | 
|  | 150 |  | 
|  | 151 | /// BinaryExprAST - Expression class for a binary operator. | 
|  | 152 | struct BinaryExprAST : public ExprAST { | 
|  | 153 | BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, | 
|  | 154 | std::unique_ptr<ExprAST> RHS) | 
|  | 155 | : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} | 
|  | 156 |  | 
|  | 157 | Value *IRGen(IRGenContext &C) const override; | 
|  | 158 |  | 
|  | 159 | char Op; | 
|  | 160 | std::unique_ptr<ExprAST> LHS, RHS; | 
|  | 161 | }; | 
|  | 162 |  | 
|  | 163 | /// CallExprAST - Expression class for function calls. | 
|  | 164 | struct CallExprAST : public ExprAST { | 
|  | 165 | CallExprAST(std::string CalleeName, | 
|  | 166 | std::vector<std::unique_ptr<ExprAST>> Args) | 
|  | 167 | : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {} | 
|  | 168 |  | 
|  | 169 | Value *IRGen(IRGenContext &C) const override; | 
|  | 170 |  | 
|  | 171 | std::string CalleeName; | 
|  | 172 | std::vector<std::unique_ptr<ExprAST>> Args; | 
|  | 173 | }; | 
|  | 174 |  | 
|  | 175 | /// IfExprAST - Expression class for if/then/else. | 
|  | 176 | struct IfExprAST : public ExprAST { | 
|  | 177 | IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then, | 
|  | 178 | std::unique_ptr<ExprAST> Else) | 
|  | 179 | : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} | 
|  | 180 | Value *IRGen(IRGenContext &C) const override; | 
|  | 181 |  | 
|  | 182 | std::unique_ptr<ExprAST> Cond, Then, Else; | 
|  | 183 | }; | 
|  | 184 |  | 
|  | 185 | /// ForExprAST - Expression class for for/in. | 
|  | 186 | struct ForExprAST : public ExprAST { | 
|  | 187 | ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start, | 
|  | 188 | std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step, | 
|  | 189 | std::unique_ptr<ExprAST> Body) | 
|  | 190 | : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)), | 
|  | 191 | Step(std::move(Step)), Body(std::move(Body)) {} | 
|  | 192 |  | 
|  | 193 | Value *IRGen(IRGenContext &C) const override; | 
|  | 194 |  | 
|  | 195 | std::string VarName; | 
|  | 196 | std::unique_ptr<ExprAST> Start, End, Step, Body; | 
|  | 197 | }; | 
|  | 198 |  | 
|  | 199 | /// VarExprAST - Expression class for var/in | 
|  | 200 | struct VarExprAST : public ExprAST { | 
|  | 201 | typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding; | 
|  | 202 | typedef std::vector<Binding> BindingList; | 
|  | 203 |  | 
|  | 204 | VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body) | 
|  | 205 | : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {} | 
|  | 206 |  | 
|  | 207 | Value *IRGen(IRGenContext &C) const override; | 
|  | 208 |  | 
|  | 209 | BindingList VarBindings; | 
|  | 210 | std::unique_ptr<ExprAST> Body; | 
|  | 211 | }; | 
|  | 212 |  | 
|  | 213 | /// PrototypeAST - This class represents the "prototype" for a function, | 
|  | 214 | /// which captures its argument names as well as if it is an operator. | 
|  | 215 | struct PrototypeAST { | 
|  | 216 | PrototypeAST(std::string Name, std::vector<std::string> Args, | 
|  | 217 | bool IsOperator = false, unsigned Precedence = 0) | 
|  | 218 | : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator), | 
|  | 219 | Precedence(Precedence) {} | 
|  | 220 |  | 
|  | 221 | Function *IRGen(IRGenContext &C) const; | 
|  | 222 | void CreateArgumentAllocas(Function *F, IRGenContext &C); | 
|  | 223 |  | 
|  | 224 | bool isUnaryOp() const { return IsOperator && Args.size() == 1; } | 
|  | 225 | bool isBinaryOp() const { return IsOperator && Args.size() == 2; } | 
|  | 226 |  | 
|  | 227 | char getOperatorName() const { | 
|  | 228 | assert(isUnaryOp() || isBinaryOp()); | 
|  | 229 | return Name[Name.size()-1]; | 
|  | 230 | } | 
|  | 231 |  | 
|  | 232 | std::string Name; | 
|  | 233 | std::vector<std::string> Args; | 
|  | 234 | bool IsOperator; | 
|  | 235 | unsigned Precedence;  // Precedence if a binary op. | 
|  | 236 | }; | 
|  | 237 |  | 
|  | 238 | /// FunctionAST - This class represents a function definition itself. | 
|  | 239 | struct FunctionAST { | 
|  | 240 | FunctionAST(std::unique_ptr<PrototypeAST> Proto, | 
|  | 241 | std::unique_ptr<ExprAST> Body) | 
|  | 242 | : Proto(std::move(Proto)), Body(std::move(Body)) {} | 
|  | 243 |  | 
|  | 244 | Function *IRGen(IRGenContext &C) const; | 
|  | 245 |  | 
|  | 246 | std::unique_ptr<PrototypeAST> Proto; | 
|  | 247 | std::unique_ptr<ExprAST> Body; | 
|  | 248 | }; | 
|  | 249 |  | 
|  | 250 | //===----------------------------------------------------------------------===// | 
|  | 251 | // Parser | 
|  | 252 | //===----------------------------------------------------------------------===// | 
|  | 253 |  | 
|  | 254 | /// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current | 
|  | 255 | /// token the parser is looking at.  getNextToken reads another token from the | 
|  | 256 | /// lexer and updates CurTok with its results. | 
|  | 257 | static int CurTok; | 
|  | 258 | static int getNextToken() { | 
|  | 259 | return CurTok = gettok(); | 
|  | 260 | } | 
|  | 261 |  | 
|  | 262 | /// BinopPrecedence - This holds the precedence for each binary operator that is | 
|  | 263 | /// defined. | 
|  | 264 | static std::map<char, int> BinopPrecedence; | 
|  | 265 |  | 
|  | 266 | /// GetTokPrecedence - Get the precedence of the pending binary operator token. | 
|  | 267 | static int GetTokPrecedence() { | 
|  | 268 | if (!isascii(CurTok)) | 
|  | 269 | return -1; | 
|  | 270 |  | 
|  | 271 | // Make sure it's a declared binop. | 
|  | 272 | int TokPrec = BinopPrecedence[CurTok]; | 
|  | 273 | if (TokPrec <= 0) return -1; | 
|  | 274 | return TokPrec; | 
|  | 275 | } | 
|  | 276 |  | 
|  | 277 | template <typename T> | 
|  | 278 | std::unique_ptr<T> ErrorU(const std::string &Str) { | 
|  | 279 | std::cerr << "Error: " << Str << "\n"; | 
|  | 280 | return nullptr; | 
|  | 281 | } | 
|  | 282 |  | 
|  | 283 | template <typename T> | 
|  | 284 | T* ErrorP(const std::string &Str) { | 
|  | 285 | std::cerr << "Error: " << Str << "\n"; | 
|  | 286 | return nullptr; | 
|  | 287 | } | 
|  | 288 |  | 
|  | 289 | static std::unique_ptr<ExprAST> ParseExpression(); | 
|  | 290 |  | 
|  | 291 | /// identifierexpr | 
|  | 292 | ///   ::= identifier | 
|  | 293 | ///   ::= identifier '(' expression* ')' | 
|  | 294 | static std::unique_ptr<ExprAST> ParseIdentifierExpr() { | 
|  | 295 | std::string IdName = IdentifierStr; | 
|  | 296 |  | 
|  | 297 | getNextToken();  // eat identifier. | 
|  | 298 |  | 
|  | 299 | if (CurTok != '(') // Simple variable ref. | 
|  | 300 | return llvm::make_unique<VariableExprAST>(IdName); | 
|  | 301 |  | 
|  | 302 | // Call. | 
|  | 303 | getNextToken();  // eat ( | 
|  | 304 | std::vector<std::unique_ptr<ExprAST>> Args; | 
|  | 305 | if (CurTok != ')') { | 
|  | 306 | while (1) { | 
|  | 307 | auto Arg = ParseExpression(); | 
|  | 308 | if (!Arg) return nullptr; | 
|  | 309 | Args.push_back(std::move(Arg)); | 
|  | 310 |  | 
|  | 311 | if (CurTok == ')') break; | 
|  | 312 |  | 
|  | 313 | if (CurTok != ',') | 
|  | 314 | return ErrorU<CallExprAST>("Expected ')' or ',' in argument list"); | 
|  | 315 | getNextToken(); | 
|  | 316 | } | 
|  | 317 | } | 
|  | 318 |  | 
|  | 319 | // Eat the ')'. | 
|  | 320 | getNextToken(); | 
|  | 321 |  | 
|  | 322 | return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); | 
|  | 323 | } | 
|  | 324 |  | 
|  | 325 | /// numberexpr ::= number | 
|  | 326 | static std::unique_ptr<NumberExprAST> ParseNumberExpr() { | 
|  | 327 | auto Result = llvm::make_unique<NumberExprAST>(NumVal); | 
|  | 328 | getNextToken(); // consume the number | 
|  | 329 | return Result; | 
|  | 330 | } | 
|  | 331 |  | 
|  | 332 | /// parenexpr ::= '(' expression ')' | 
|  | 333 | static std::unique_ptr<ExprAST> ParseParenExpr() { | 
|  | 334 | getNextToken();  // eat (. | 
|  | 335 | auto V = ParseExpression(); | 
|  | 336 | if (!V) | 
|  | 337 | return nullptr; | 
|  | 338 |  | 
|  | 339 | if (CurTok != ')') | 
|  | 340 | return ErrorU<ExprAST>("expected ')'"); | 
|  | 341 | getNextToken();  // eat ). | 
|  | 342 | return V; | 
|  | 343 | } | 
|  | 344 |  | 
|  | 345 | /// ifexpr ::= 'if' expression 'then' expression 'else' expression | 
|  | 346 | static std::unique_ptr<ExprAST> ParseIfExpr() { | 
|  | 347 | getNextToken();  // eat the if. | 
|  | 348 |  | 
|  | 349 | // condition. | 
|  | 350 | auto Cond = ParseExpression(); | 
|  | 351 | if (!Cond) | 
|  | 352 | return nullptr; | 
|  | 353 |  | 
|  | 354 | if (CurTok != tok_then) | 
|  | 355 | return ErrorU<ExprAST>("expected then"); | 
|  | 356 | getNextToken();  // eat the then | 
|  | 357 |  | 
|  | 358 | auto Then = ParseExpression(); | 
|  | 359 | if (!Then) | 
|  | 360 | return nullptr; | 
|  | 361 |  | 
|  | 362 | if (CurTok != tok_else) | 
|  | 363 | return ErrorU<ExprAST>("expected else"); | 
|  | 364 |  | 
|  | 365 | getNextToken(); | 
|  | 366 |  | 
|  | 367 | auto Else = ParseExpression(); | 
|  | 368 | if (!Else) | 
|  | 369 | return nullptr; | 
|  | 370 |  | 
|  | 371 | return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), | 
|  | 372 | std::move(Else)); | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression | 
|  | 376 | static std::unique_ptr<ForExprAST> ParseForExpr() { | 
|  | 377 | getNextToken();  // eat the for. | 
|  | 378 |  | 
|  | 379 | if (CurTok != tok_identifier) | 
|  | 380 | return ErrorU<ForExprAST>("expected identifier after for"); | 
|  | 381 |  | 
|  | 382 | std::string IdName = IdentifierStr; | 
|  | 383 | getNextToken();  // eat identifier. | 
|  | 384 |  | 
|  | 385 | if (CurTok != '=') | 
|  | 386 | return ErrorU<ForExprAST>("expected '=' after for"); | 
|  | 387 | getNextToken();  // eat '='. | 
|  | 388 |  | 
|  | 389 |  | 
|  | 390 | auto Start = ParseExpression(); | 
|  | 391 | if (!Start) | 
|  | 392 | return nullptr; | 
|  | 393 | if (CurTok != ',') | 
|  | 394 | return ErrorU<ForExprAST>("expected ',' after for start value"); | 
|  | 395 | getNextToken(); | 
|  | 396 |  | 
|  | 397 | auto End = ParseExpression(); | 
|  | 398 | if (!End) | 
|  | 399 | return nullptr; | 
|  | 400 |  | 
|  | 401 | // The step value is optional. | 
|  | 402 | std::unique_ptr<ExprAST> Step; | 
|  | 403 | if (CurTok == ',') { | 
|  | 404 | getNextToken(); | 
|  | 405 | Step = ParseExpression(); | 
|  | 406 | if (!Step) | 
|  | 407 | return nullptr; | 
|  | 408 | } | 
|  | 409 |  | 
|  | 410 | if (CurTok != tok_in) | 
|  | 411 | return ErrorU<ForExprAST>("expected 'in' after for"); | 
|  | 412 | getNextToken();  // eat 'in'. | 
|  | 413 |  | 
|  | 414 | auto Body = ParseExpression(); | 
|  | 415 | if (Body) | 
|  | 416 | return nullptr; | 
|  | 417 |  | 
|  | 418 | return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End), | 
|  | 419 | std::move(Step), std::move(Body)); | 
|  | 420 | } | 
|  | 421 |  | 
|  | 422 | /// varexpr ::= 'var' identifier ('=' expression)? | 
|  | 423 | //                    (',' identifier ('=' expression)?)* 'in' expression | 
|  | 424 | static std::unique_ptr<VarExprAST> ParseVarExpr() { | 
|  | 425 | getNextToken();  // eat the var. | 
|  | 426 |  | 
|  | 427 | VarExprAST::BindingList VarBindings; | 
|  | 428 |  | 
|  | 429 | // At least one variable name is required. | 
|  | 430 | if (CurTok != tok_identifier) | 
|  | 431 | return ErrorU<VarExprAST>("expected identifier after var"); | 
|  | 432 |  | 
|  | 433 | while (1) { | 
|  | 434 | std::string Name = IdentifierStr; | 
|  | 435 | getNextToken();  // eat identifier. | 
|  | 436 |  | 
|  | 437 | // Read the optional initializer. | 
|  | 438 | std::unique_ptr<ExprAST> Init; | 
|  | 439 | if (CurTok == '=') { | 
|  | 440 | getNextToken(); // eat the '='. | 
|  | 441 |  | 
|  | 442 | Init = ParseExpression(); | 
|  | 443 | if (!Init) | 
|  | 444 | return nullptr; | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init))); | 
|  | 448 |  | 
|  | 449 | // End of var list, exit loop. | 
|  | 450 | if (CurTok != ',') break; | 
|  | 451 | getNextToken(); // eat the ','. | 
|  | 452 |  | 
|  | 453 | if (CurTok != tok_identifier) | 
|  | 454 | return ErrorU<VarExprAST>("expected identifier list after var"); | 
|  | 455 | } | 
|  | 456 |  | 
|  | 457 | // At this point, we have to have 'in'. | 
|  | 458 | if (CurTok != tok_in) | 
|  | 459 | return ErrorU<VarExprAST>("expected 'in' keyword after 'var'"); | 
|  | 460 | getNextToken();  // eat 'in'. | 
|  | 461 |  | 
|  | 462 | auto Body = ParseExpression(); | 
|  | 463 | if (!Body) | 
|  | 464 | return nullptr; | 
|  | 465 |  | 
|  | 466 | return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body)); | 
|  | 467 | } | 
|  | 468 |  | 
|  | 469 | /// primary | 
|  | 470 | ///   ::= identifierexpr | 
|  | 471 | ///   ::= numberexpr | 
|  | 472 | ///   ::= parenexpr | 
|  | 473 | ///   ::= ifexpr | 
|  | 474 | ///   ::= forexpr | 
|  | 475 | ///   ::= varexpr | 
|  | 476 | static std::unique_ptr<ExprAST> ParsePrimary() { | 
|  | 477 | switch (CurTok) { | 
|  | 478 | default: return ErrorU<ExprAST>("unknown token when expecting an expression"); | 
|  | 479 | case tok_identifier: return ParseIdentifierExpr(); | 
|  | 480 | case tok_number:     return ParseNumberExpr(); | 
|  | 481 | case '(':            return ParseParenExpr(); | 
|  | 482 | case tok_if:         return ParseIfExpr(); | 
|  | 483 | case tok_for:        return ParseForExpr(); | 
|  | 484 | case tok_var:        return ParseVarExpr(); | 
|  | 485 | } | 
|  | 486 | } | 
|  | 487 |  | 
|  | 488 | /// unary | 
|  | 489 | ///   ::= primary | 
|  | 490 | ///   ::= '!' unary | 
|  | 491 | static std::unique_ptr<ExprAST> ParseUnary() { | 
|  | 492 | // If the current token is not an operator, it must be a primary expr. | 
|  | 493 | if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') | 
|  | 494 | return ParsePrimary(); | 
|  | 495 |  | 
|  | 496 | // If this is a unary operator, read it. | 
|  | 497 | int Opc = CurTok; | 
|  | 498 | getNextToken(); | 
|  | 499 | if (auto Operand = ParseUnary()) | 
|  | 500 | return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand)); | 
|  | 501 | return nullptr; | 
|  | 502 | } | 
|  | 503 |  | 
|  | 504 | /// binoprhs | 
|  | 505 | ///   ::= ('+' unary)* | 
|  | 506 | static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, | 
|  | 507 | std::unique_ptr<ExprAST> LHS) { | 
|  | 508 | // If this is a binop, find its precedence. | 
|  | 509 | while (1) { | 
|  | 510 | int TokPrec = GetTokPrecedence(); | 
|  | 511 |  | 
|  | 512 | // If this is a binop that binds at least as tightly as the current binop, | 
|  | 513 | // consume it, otherwise we are done. | 
|  | 514 | if (TokPrec < ExprPrec) | 
|  | 515 | return LHS; | 
|  | 516 |  | 
|  | 517 | // Okay, we know this is a binop. | 
|  | 518 | int BinOp = CurTok; | 
|  | 519 | getNextToken();  // eat binop | 
|  | 520 |  | 
|  | 521 | // Parse the unary expression after the binary operator. | 
|  | 522 | auto RHS = ParseUnary(); | 
|  | 523 | if (!RHS) | 
|  | 524 | return nullptr; | 
|  | 525 |  | 
|  | 526 | // If BinOp binds less tightly with RHS than the operator after RHS, let | 
|  | 527 | // the pending operator take RHS as its LHS. | 
|  | 528 | int NextPrec = GetTokPrecedence(); | 
|  | 529 | if (TokPrec < NextPrec) { | 
|  | 530 | RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS)); | 
|  | 531 | if (!RHS) | 
|  | 532 | return nullptr; | 
|  | 533 | } | 
|  | 534 |  | 
|  | 535 | // Merge LHS/RHS. | 
|  | 536 | LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); | 
|  | 537 | } | 
|  | 538 | } | 
|  | 539 |  | 
|  | 540 | /// expression | 
|  | 541 | ///   ::= unary binoprhs | 
|  | 542 | /// | 
|  | 543 | static std::unique_ptr<ExprAST> ParseExpression() { | 
|  | 544 | auto LHS = ParseUnary(); | 
|  | 545 | if (!LHS) | 
|  | 546 | return nullptr; | 
|  | 547 |  | 
|  | 548 | return ParseBinOpRHS(0, std::move(LHS)); | 
|  | 549 | } | 
|  | 550 |  | 
|  | 551 | /// prototype | 
|  | 552 | ///   ::= id '(' id* ')' | 
|  | 553 | ///   ::= binary LETTER number? (id, id) | 
|  | 554 | ///   ::= unary LETTER (id) | 
|  | 555 | static std::unique_ptr<PrototypeAST> ParsePrototype() { | 
|  | 556 | std::string FnName; | 
|  | 557 |  | 
|  | 558 | unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. | 
|  | 559 | unsigned BinaryPrecedence = 30; | 
|  | 560 |  | 
|  | 561 | switch (CurTok) { | 
|  | 562 | default: | 
|  | 563 | return ErrorU<PrototypeAST>("Expected function name in prototype"); | 
|  | 564 | case tok_identifier: | 
|  | 565 | FnName = IdentifierStr; | 
|  | 566 | Kind = 0; | 
|  | 567 | getNextToken(); | 
|  | 568 | break; | 
|  | 569 | case tok_unary: | 
|  | 570 | getNextToken(); | 
|  | 571 | if (!isascii(CurTok)) | 
|  | 572 | return ErrorU<PrototypeAST>("Expected unary operator"); | 
|  | 573 | FnName = "unary"; | 
|  | 574 | FnName += (char)CurTok; | 
|  | 575 | Kind = 1; | 
|  | 576 | getNextToken(); | 
|  | 577 | break; | 
|  | 578 | case tok_binary: | 
|  | 579 | getNextToken(); | 
|  | 580 | if (!isascii(CurTok)) | 
|  | 581 | return ErrorU<PrototypeAST>("Expected binary operator"); | 
|  | 582 | FnName = "binary"; | 
|  | 583 | FnName += (char)CurTok; | 
|  | 584 | Kind = 2; | 
|  | 585 | getNextToken(); | 
|  | 586 |  | 
|  | 587 | // Read the precedence if present. | 
|  | 588 | if (CurTok == tok_number) { | 
|  | 589 | if (NumVal < 1 || NumVal > 100) | 
|  | 590 | return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100"); | 
|  | 591 | BinaryPrecedence = (unsigned)NumVal; | 
|  | 592 | getNextToken(); | 
|  | 593 | } | 
|  | 594 | break; | 
|  | 595 | } | 
|  | 596 |  | 
|  | 597 | if (CurTok != '(') | 
|  | 598 | return ErrorU<PrototypeAST>("Expected '(' in prototype"); | 
|  | 599 |  | 
|  | 600 | std::vector<std::string> ArgNames; | 
|  | 601 | while (getNextToken() == tok_identifier) | 
|  | 602 | ArgNames.push_back(IdentifierStr); | 
|  | 603 | if (CurTok != ')') | 
|  | 604 | return ErrorU<PrototypeAST>("Expected ')' in prototype"); | 
|  | 605 |  | 
|  | 606 | // success. | 
|  | 607 | getNextToken();  // eat ')'. | 
|  | 608 |  | 
|  | 609 | // Verify right number of names for operator. | 
|  | 610 | if (Kind && ArgNames.size() != Kind) | 
|  | 611 | return ErrorU<PrototypeAST>("Invalid number of operands for operator"); | 
|  | 612 |  | 
|  | 613 | return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0, | 
|  | 614 | BinaryPrecedence); | 
|  | 615 | } | 
|  | 616 |  | 
|  | 617 | /// definition ::= 'def' prototype expression | 
|  | 618 | static std::unique_ptr<FunctionAST> ParseDefinition() { | 
|  | 619 | getNextToken();  // eat def. | 
|  | 620 | auto Proto = ParsePrototype(); | 
|  | 621 | if (!Proto) | 
|  | 622 | return nullptr; | 
|  | 623 |  | 
|  | 624 | if (auto Body = ParseExpression()) | 
|  | 625 | return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body)); | 
|  | 626 | return nullptr; | 
|  | 627 | } | 
|  | 628 |  | 
|  | 629 | /// toplevelexpr ::= expression | 
|  | 630 | static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { | 
|  | 631 | if (auto E = ParseExpression()) { | 
|  | 632 | // Make an anonymous proto. | 
|  | 633 | auto Proto = | 
|  | 634 | llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>()); | 
|  | 635 | return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); | 
|  | 636 | } | 
|  | 637 | return nullptr; | 
|  | 638 | } | 
|  | 639 |  | 
|  | 640 | /// external ::= 'extern' prototype | 
|  | 641 | static std::unique_ptr<PrototypeAST> ParseExtern() { | 
|  | 642 | getNextToken();  // eat extern. | 
|  | 643 | return ParsePrototype(); | 
|  | 644 | } | 
|  | 645 |  | 
|  | 646 | //===----------------------------------------------------------------------===// | 
|  | 647 | // Code Generation | 
|  | 648 | //===----------------------------------------------------------------------===// | 
|  | 649 |  | 
|  | 650 | // FIXME: Obviously we can do better than this | 
|  | 651 | std::string GenerateUniqueName(const std::string &Root) { | 
|  | 652 | static int i = 0; | 
|  | 653 | std::ostringstream NameStream; | 
|  | 654 | NameStream << Root << ++i; | 
|  | 655 | return NameStream.str(); | 
|  | 656 | } | 
|  | 657 |  | 
|  | 658 | std::string MakeLegalFunctionName(std::string Name) | 
|  | 659 | { | 
|  | 660 | std::string NewName; | 
|  | 661 | assert(!Name.empty() && "Base name must not be empty"); | 
|  | 662 |  | 
|  | 663 | // Start with what we have | 
|  | 664 | NewName = Name; | 
|  | 665 |  | 
|  | 666 | // Look for a numberic first character | 
|  | 667 | if (NewName.find_first_of("0123456789") == 0) { | 
|  | 668 | NewName.insert(0, 1, 'n'); | 
|  | 669 | } | 
|  | 670 |  | 
|  | 671 | // Replace illegal characters with their ASCII equivalent | 
|  | 672 | std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | 
|  | 673 | size_t pos; | 
|  | 674 | while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) { | 
|  | 675 | std::ostringstream NumStream; | 
|  | 676 | NumStream << (int)NewName.at(pos); | 
|  | 677 | NewName = NewName.replace(pos, 1, NumStream.str()); | 
|  | 678 | } | 
|  | 679 |  | 
|  | 680 | return NewName; | 
|  | 681 | } | 
|  | 682 |  | 
|  | 683 | class SessionContext { | 
|  | 684 | public: | 
|  | 685 | SessionContext(LLVMContext &C) : Context(C) {} | 
|  | 686 | LLVMContext& getLLVMContext() const { return Context; } | 
|  | 687 | void addPrototypeAST(std::unique_ptr<PrototypeAST> P); | 
|  | 688 | PrototypeAST* getPrototypeAST(const std::string &Name); | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 689 | private: | 
|  | 690 | typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap; | 
|  | 691 | LLVMContext &Context; | 
|  | 692 | PrototypeMap Prototypes; | 
|  | 693 | }; | 
|  | 694 |  | 
|  | 695 | void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) { | 
|  | 696 | Prototypes[P->Name] = std::move(P); | 
|  | 697 | } | 
|  | 698 |  | 
|  | 699 | PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) { | 
|  | 700 | PrototypeMap::iterator I = Prototypes.find(Name); | 
|  | 701 | if (I != Prototypes.end()) | 
|  | 702 | return I->second.get(); | 
|  | 703 | return nullptr; | 
|  | 704 | } | 
|  | 705 |  | 
|  | 706 | class IRGenContext { | 
|  | 707 | public: | 
|  | 708 |  | 
|  | 709 | IRGenContext(SessionContext &S) | 
|  | 710 | : Session(S), | 
|  | 711 | M(new Module(GenerateUniqueName("jit_module_"), | 
|  | 712 | Session.getLLVMContext())), | 
|  | 713 | Builder(Session.getLLVMContext()) {} | 
|  | 714 |  | 
|  | 715 | SessionContext& getSession() { return Session; } | 
|  | 716 | Module& getM() const { return *M; } | 
|  | 717 | std::unique_ptr<Module> takeM() { return std::move(M); } | 
|  | 718 | IRBuilder<>& getBuilder() { return Builder; } | 
|  | 719 | LLVMContext& getLLVMContext() { return Session.getLLVMContext(); } | 
|  | 720 | Function* getPrototype(const std::string &Name); | 
|  | 721 |  | 
|  | 722 | std::map<std::string, AllocaInst*> NamedValues; | 
|  | 723 | private: | 
|  | 724 | SessionContext &Session; | 
|  | 725 | std::unique_ptr<Module> M; | 
|  | 726 | IRBuilder<> Builder; | 
|  | 727 | }; | 
|  | 728 |  | 
|  | 729 | Function* IRGenContext::getPrototype(const std::string &Name) { | 
|  | 730 | if (Function *ExistingProto = M->getFunction(Name)) | 
|  | 731 | return ExistingProto; | 
|  | 732 | if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name)) | 
|  | 733 | return ProtoAST->IRGen(*this); | 
|  | 734 | return nullptr; | 
|  | 735 | } | 
|  | 736 |  | 
|  | 737 | /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of | 
|  | 738 | /// the function.  This is used for mutable variables etc. | 
|  | 739 | static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, | 
|  | 740 | const std::string &VarName) { | 
|  | 741 | IRBuilder<> TmpB(&TheFunction->getEntryBlock(), | 
|  | 742 | TheFunction->getEntryBlock().begin()); | 
|  | 743 | return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, | 
|  | 744 | VarName.c_str()); | 
|  | 745 | } | 
|  | 746 |  | 
|  | 747 | Value *NumberExprAST::IRGen(IRGenContext &C) const { | 
|  | 748 | return ConstantFP::get(C.getLLVMContext(), APFloat(Val)); | 
|  | 749 | } | 
|  | 750 |  | 
|  | 751 | Value *VariableExprAST::IRGen(IRGenContext &C) const { | 
|  | 752 | // Look this variable up in the function. | 
|  | 753 | Value *V = C.NamedValues[Name]; | 
|  | 754 |  | 
|  | 755 | if (V == 0) | 
|  | 756 | return ErrorP<Value>("Unknown variable name '" + Name + "'"); | 
|  | 757 |  | 
|  | 758 | // Load the value. | 
|  | 759 | return C.getBuilder().CreateLoad(V, Name.c_str()); | 
|  | 760 | } | 
|  | 761 |  | 
|  | 762 | Value *UnaryExprAST::IRGen(IRGenContext &C) const { | 
|  | 763 | if (Value *OperandV = Operand->IRGen(C)) { | 
|  | 764 | std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode); | 
|  | 765 | if (Function *F = C.getPrototype(FnName)) | 
|  | 766 | return C.getBuilder().CreateCall(F, OperandV, "unop"); | 
|  | 767 | return ErrorP<Value>("Unknown unary operator"); | 
|  | 768 | } | 
|  | 769 |  | 
|  | 770 | // Could not codegen operand - return null. | 
|  | 771 | return nullptr; | 
|  | 772 | } | 
|  | 773 |  | 
|  | 774 | Value *BinaryExprAST::IRGen(IRGenContext &C) const { | 
|  | 775 | // Special case '=' because we don't want to emit the LHS as an expression. | 
|  | 776 | if (Op == '=') { | 
|  | 777 | // Assignment requires the LHS to be an identifier. | 
|  | 778 | auto LHSVar = static_cast<VariableExprAST&>(*LHS); | 
|  | 779 | // Codegen the RHS. | 
|  | 780 | Value *Val = RHS->IRGen(C); | 
|  | 781 | if (!Val) return nullptr; | 
|  | 782 |  | 
|  | 783 | // Look up the name. | 
|  | 784 | if (auto Variable = C.NamedValues[LHSVar.Name]) { | 
|  | 785 | C.getBuilder().CreateStore(Val, Variable); | 
|  | 786 | return Val; | 
|  | 787 | } | 
|  | 788 | return ErrorP<Value>("Unknown variable name"); | 
|  | 789 | } | 
|  | 790 |  | 
|  | 791 | Value *L = LHS->IRGen(C); | 
|  | 792 | Value *R = RHS->IRGen(C); | 
|  | 793 | if (!L || !R) return nullptr; | 
|  | 794 |  | 
|  | 795 | switch (Op) { | 
|  | 796 | case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp"); | 
|  | 797 | case '-': return C.getBuilder().CreateFSub(L, R, "subtmp"); | 
|  | 798 | case '*': return C.getBuilder().CreateFMul(L, R, "multmp"); | 
|  | 799 | case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp"); | 
|  | 800 | case '<': | 
|  | 801 | L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp"); | 
|  | 802 | // Convert bool 0/1 to double 0.0 or 1.0 | 
|  | 803 | return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), | 
|  | 804 | "booltmp"); | 
|  | 805 | default: break; | 
|  | 806 | } | 
|  | 807 |  | 
|  | 808 | // If it wasn't a builtin binary operator, it must be a user defined one. Emit | 
|  | 809 | // a call to it. | 
|  | 810 | std::string FnName = MakeLegalFunctionName(std::string("binary")+Op); | 
|  | 811 | if (Function *F = C.getPrototype(FnName)) { | 
|  | 812 | Value *Ops[] = { L, R }; | 
|  | 813 | return C.getBuilder().CreateCall(F, Ops, "binop"); | 
|  | 814 | } | 
|  | 815 |  | 
|  | 816 | return ErrorP<Value>("Unknown binary operator"); | 
|  | 817 | } | 
|  | 818 |  | 
|  | 819 | Value *CallExprAST::IRGen(IRGenContext &C) const { | 
|  | 820 | // Look up the name in the global module table. | 
|  | 821 | if (auto CalleeF = C.getPrototype(CalleeName)) { | 
|  | 822 | // If argument mismatch error. | 
|  | 823 | if (CalleeF->arg_size() != Args.size()) | 
|  | 824 | return ErrorP<Value>("Incorrect # arguments passed"); | 
|  | 825 |  | 
|  | 826 | std::vector<Value*> ArgsV; | 
|  | 827 | for (unsigned i = 0, e = Args.size(); i != e; ++i) { | 
|  | 828 | ArgsV.push_back(Args[i]->IRGen(C)); | 
|  | 829 | if (!ArgsV.back()) return nullptr; | 
|  | 830 | } | 
|  | 831 |  | 
|  | 832 | return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp"); | 
|  | 833 | } | 
|  | 834 |  | 
|  | 835 | return ErrorP<Value>("Unknown function referenced"); | 
|  | 836 | } | 
|  | 837 |  | 
|  | 838 | Value *IfExprAST::IRGen(IRGenContext &C) const { | 
|  | 839 | Value *CondV = Cond->IRGen(C); | 
|  | 840 | if (!CondV) return nullptr; | 
|  | 841 |  | 
|  | 842 | // Convert condition to a bool by comparing equal to 0.0. | 
|  | 843 | ConstantFP *FPZero = | 
|  | 844 | ConstantFP::get(C.getLLVMContext(), APFloat(0.0)); | 
|  | 845 | CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond"); | 
|  | 846 |  | 
|  | 847 | Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); | 
|  | 848 |  | 
|  | 849 | // Create blocks for the then and else cases.  Insert the 'then' block at the | 
|  | 850 | // end of the function. | 
|  | 851 | BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction); | 
|  | 852 | BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else"); | 
|  | 853 | BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont"); | 
|  | 854 |  | 
|  | 855 | C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB); | 
|  | 856 |  | 
|  | 857 | // Emit then value. | 
|  | 858 | C.getBuilder().SetInsertPoint(ThenBB); | 
|  | 859 |  | 
|  | 860 | Value *ThenV = Then->IRGen(C); | 
|  | 861 | if (!ThenV) return nullptr; | 
|  | 862 |  | 
|  | 863 | C.getBuilder().CreateBr(MergeBB); | 
|  | 864 | // Codegen of 'Then' can change the current block, update ThenBB for the PHI. | 
|  | 865 | ThenBB = C.getBuilder().GetInsertBlock(); | 
|  | 866 |  | 
|  | 867 | // Emit else block. | 
|  | 868 | TheFunction->getBasicBlockList().push_back(ElseBB); | 
|  | 869 | C.getBuilder().SetInsertPoint(ElseBB); | 
|  | 870 |  | 
|  | 871 | Value *ElseV = Else->IRGen(C); | 
|  | 872 | if (!ElseV) return nullptr; | 
|  | 873 |  | 
|  | 874 | C.getBuilder().CreateBr(MergeBB); | 
|  | 875 | // Codegen of 'Else' can change the current block, update ElseBB for the PHI. | 
|  | 876 | ElseBB = C.getBuilder().GetInsertBlock(); | 
|  | 877 |  | 
|  | 878 | // Emit merge block. | 
|  | 879 | TheFunction->getBasicBlockList().push_back(MergeBB); | 
|  | 880 | C.getBuilder().SetInsertPoint(MergeBB); | 
|  | 881 | PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, | 
|  | 882 | "iftmp"); | 
|  | 883 |  | 
|  | 884 | PN->addIncoming(ThenV, ThenBB); | 
|  | 885 | PN->addIncoming(ElseV, ElseBB); | 
|  | 886 | return PN; | 
|  | 887 | } | 
|  | 888 |  | 
|  | 889 | Value *ForExprAST::IRGen(IRGenContext &C) const { | 
|  | 890 | // Output this as: | 
|  | 891 | //   var = alloca double | 
|  | 892 | //   ... | 
|  | 893 | //   start = startexpr | 
|  | 894 | //   store start -> var | 
|  | 895 | //   goto loop | 
|  | 896 | // loop: | 
|  | 897 | //   ... | 
|  | 898 | //   bodyexpr | 
|  | 899 | //   ... | 
|  | 900 | // loopend: | 
|  | 901 | //   step = stepexpr | 
|  | 902 | //   endcond = endexpr | 
|  | 903 | // | 
|  | 904 | //   curvar = load var | 
|  | 905 | //   nextvar = curvar + step | 
|  | 906 | //   store nextvar -> var | 
|  | 907 | //   br endcond, loop, endloop | 
|  | 908 | // outloop: | 
|  | 909 |  | 
|  | 910 | Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); | 
|  | 911 |  | 
|  | 912 | // Create an alloca for the variable in the entry block. | 
|  | 913 | AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); | 
|  | 914 |  | 
|  | 915 | // Emit the start code first, without 'variable' in scope. | 
|  | 916 | Value *StartVal = Start->IRGen(C); | 
|  | 917 | if (!StartVal) return nullptr; | 
|  | 918 |  | 
|  | 919 | // Store the value into the alloca. | 
|  | 920 | C.getBuilder().CreateStore(StartVal, Alloca); | 
|  | 921 |  | 
|  | 922 | // Make the new basic block for the loop header, inserting after current | 
|  | 923 | // block. | 
|  | 924 | BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); | 
|  | 925 |  | 
|  | 926 | // Insert an explicit fall through from the current block to the LoopBB. | 
|  | 927 | C.getBuilder().CreateBr(LoopBB); | 
|  | 928 |  | 
|  | 929 | // Start insertion in LoopBB. | 
|  | 930 | C.getBuilder().SetInsertPoint(LoopBB); | 
|  | 931 |  | 
|  | 932 | // Within the loop, the variable is defined equal to the PHI node.  If it | 
|  | 933 | // shadows an existing variable, we have to restore it, so save it now. | 
|  | 934 | AllocaInst *OldVal = C.NamedValues[VarName]; | 
|  | 935 | C.NamedValues[VarName] = Alloca; | 
|  | 936 |  | 
|  | 937 | // Emit the body of the loop.  This, like any other expr, can change the | 
|  | 938 | // current BB.  Note that we ignore the value computed by the body, but don't | 
|  | 939 | // allow an error. | 
|  | 940 | if (!Body->IRGen(C)) | 
|  | 941 | return nullptr; | 
|  | 942 |  | 
|  | 943 | // Emit the step value. | 
|  | 944 | Value *StepVal; | 
|  | 945 | if (Step) { | 
|  | 946 | StepVal = Step->IRGen(C); | 
|  | 947 | if (!StepVal) return nullptr; | 
|  | 948 | } else { | 
|  | 949 | // If not specified, use 1.0. | 
|  | 950 | StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); | 
|  | 951 | } | 
|  | 952 |  | 
|  | 953 | // Compute the end condition. | 
|  | 954 | Value *EndCond = End->IRGen(C); | 
|  | 955 | if (EndCond == 0) return EndCond; | 
|  | 956 |  | 
|  | 957 | // Reload, increment, and restore the alloca.  This handles the case where | 
|  | 958 | // the body of the loop mutates the variable. | 
|  | 959 | Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str()); | 
|  | 960 | Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar"); | 
|  | 961 | C.getBuilder().CreateStore(NextVar, Alloca); | 
|  | 962 |  | 
|  | 963 | // Convert condition to a bool by comparing equal to 0.0. | 
|  | 964 | EndCond = C.getBuilder().CreateFCmpONE(EndCond, | 
|  | 965 | ConstantFP::get(getGlobalContext(), APFloat(0.0)), | 
|  | 966 | "loopcond"); | 
|  | 967 |  | 
|  | 968 | // Create the "after loop" block and insert it. | 
|  | 969 | BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); | 
|  | 970 |  | 
|  | 971 | // Insert the conditional branch into the end of LoopEndBB. | 
|  | 972 | C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB); | 
|  | 973 |  | 
|  | 974 | // Any new code will be inserted in AfterBB. | 
|  | 975 | C.getBuilder().SetInsertPoint(AfterBB); | 
|  | 976 |  | 
|  | 977 | // Restore the unshadowed variable. | 
|  | 978 | if (OldVal) | 
|  | 979 | C.NamedValues[VarName] = OldVal; | 
|  | 980 | else | 
|  | 981 | C.NamedValues.erase(VarName); | 
|  | 982 |  | 
|  | 983 |  | 
|  | 984 | // for expr always returns 0.0. | 
|  | 985 | return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); | 
|  | 986 | } | 
|  | 987 |  | 
|  | 988 | Value *VarExprAST::IRGen(IRGenContext &C) const { | 
|  | 989 | std::vector<AllocaInst *> OldBindings; | 
|  | 990 |  | 
|  | 991 | Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); | 
|  | 992 |  | 
|  | 993 | // Register all variables and emit their initializer. | 
|  | 994 | for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) { | 
|  | 995 | auto &VarName = VarBindings[i].first; | 
|  | 996 | auto &Init = VarBindings[i].second; | 
|  | 997 |  | 
|  | 998 | // Emit the initializer before adding the variable to scope, this prevents | 
|  | 999 | // the initializer from referencing the variable itself, and permits stuff | 
|  | 1000 | // like this: | 
|  | 1001 | //  var a = 1 in | 
|  | 1002 | //    var a = a in ...   # refers to outer 'a'. | 
|  | 1003 | Value *InitVal; | 
|  | 1004 | if (Init) { | 
|  | 1005 | InitVal = Init->IRGen(C); | 
|  | 1006 | if (!InitVal) return nullptr; | 
|  | 1007 | } else // If not specified, use 0.0. | 
|  | 1008 | InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); | 
|  | 1009 |  | 
|  | 1010 | AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); | 
|  | 1011 | C.getBuilder().CreateStore(InitVal, Alloca); | 
|  | 1012 |  | 
|  | 1013 | // Remember the old variable binding so that we can restore the binding when | 
|  | 1014 | // we unrecurse. | 
|  | 1015 | OldBindings.push_back(C.NamedValues[VarName]); | 
|  | 1016 |  | 
|  | 1017 | // Remember this binding. | 
|  | 1018 | C.NamedValues[VarName] = Alloca; | 
|  | 1019 | } | 
|  | 1020 |  | 
|  | 1021 | // Codegen the body, now that all vars are in scope. | 
|  | 1022 | Value *BodyVal = Body->IRGen(C); | 
|  | 1023 | if (!BodyVal) return nullptr; | 
|  | 1024 |  | 
|  | 1025 | // Pop all our variables from scope. | 
|  | 1026 | for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) | 
|  | 1027 | C.NamedValues[VarBindings[i].first] = OldBindings[i]; | 
|  | 1028 |  | 
|  | 1029 | // Return the body computation. | 
|  | 1030 | return BodyVal; | 
|  | 1031 | } | 
|  | 1032 |  | 
|  | 1033 | Function *PrototypeAST::IRGen(IRGenContext &C) const { | 
|  | 1034 | std::string FnName = MakeLegalFunctionName(Name); | 
|  | 1035 |  | 
|  | 1036 | // Make the function type:  double(double,double) etc. | 
|  | 1037 | std::vector<Type*> Doubles(Args.size(), | 
|  | 1038 | Type::getDoubleTy(getGlobalContext())); | 
|  | 1039 | FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), | 
|  | 1040 | Doubles, false); | 
|  | 1041 | Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, | 
|  | 1042 | &C.getM()); | 
|  | 1043 |  | 
|  | 1044 | // If F conflicted, there was already something named 'FnName'.  If it has a | 
|  | 1045 | // body, don't allow redefinition or reextern. | 
|  | 1046 | if (F->getName() != FnName) { | 
|  | 1047 | // Delete the one we just made and get the existing one. | 
|  | 1048 | F->eraseFromParent(); | 
|  | 1049 | F = C.getM().getFunction(Name); | 
|  | 1050 |  | 
|  | 1051 | // If F already has a body, reject this. | 
|  | 1052 | if (!F->empty()) { | 
|  | 1053 | ErrorP<Function>("redefinition of function"); | 
|  | 1054 | return nullptr; | 
|  | 1055 | } | 
|  | 1056 |  | 
|  | 1057 | // If F took a different number of args, reject. | 
|  | 1058 | if (F->arg_size() != Args.size()) { | 
|  | 1059 | ErrorP<Function>("redefinition of function with different # args"); | 
|  | 1060 | return nullptr; | 
|  | 1061 | } | 
|  | 1062 | } | 
|  | 1063 |  | 
|  | 1064 | // Set names for all arguments. | 
|  | 1065 | unsigned Idx = 0; | 
|  | 1066 | for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); | 
|  | 1067 | ++AI, ++Idx) | 
|  | 1068 | AI->setName(Args[Idx]); | 
|  | 1069 |  | 
|  | 1070 | return F; | 
|  | 1071 | } | 
|  | 1072 |  | 
|  | 1073 | /// CreateArgumentAllocas - Create an alloca for each argument and register the | 
|  | 1074 | /// argument in the symbol table so that references to it will succeed. | 
|  | 1075 | void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { | 
|  | 1076 | Function::arg_iterator AI = F->arg_begin(); | 
|  | 1077 | for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) { | 
|  | 1078 | // Create an alloca for this variable. | 
|  | 1079 | AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); | 
|  | 1080 |  | 
|  | 1081 | // Store the initial value into the alloca. | 
|  | 1082 | C.getBuilder().CreateStore(AI, Alloca); | 
|  | 1083 |  | 
|  | 1084 | // Add arguments to variable symbol table. | 
|  | 1085 | C.NamedValues[Args[Idx]] = Alloca; | 
|  | 1086 | } | 
|  | 1087 | } | 
|  | 1088 |  | 
|  | 1089 | Function *FunctionAST::IRGen(IRGenContext &C) const { | 
|  | 1090 | C.NamedValues.clear(); | 
|  | 1091 |  | 
|  | 1092 | Function *TheFunction = Proto->IRGen(C); | 
|  | 1093 | if (!TheFunction) | 
|  | 1094 | return nullptr; | 
|  | 1095 |  | 
|  | 1096 | // If this is an operator, install it. | 
|  | 1097 | if (Proto->isBinaryOp()) | 
|  | 1098 | BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence; | 
|  | 1099 |  | 
|  | 1100 | // Create a new basic block to start insertion into. | 
|  | 1101 | BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); | 
|  | 1102 | C.getBuilder().SetInsertPoint(BB); | 
|  | 1103 |  | 
|  | 1104 | // Add all arguments to the symbol table and create their allocas. | 
|  | 1105 | Proto->CreateArgumentAllocas(TheFunction, C); | 
|  | 1106 |  | 
|  | 1107 | if (Value *RetVal = Body->IRGen(C)) { | 
|  | 1108 | // Finish off the function. | 
|  | 1109 | C.getBuilder().CreateRet(RetVal); | 
|  | 1110 |  | 
|  | 1111 | // Validate the generated code, checking for consistency. | 
|  | 1112 | verifyFunction(*TheFunction); | 
|  | 1113 |  | 
|  | 1114 | return TheFunction; | 
|  | 1115 | } | 
|  | 1116 |  | 
|  | 1117 | // Error reading body, remove function. | 
|  | 1118 | TheFunction->eraseFromParent(); | 
|  | 1119 |  | 
|  | 1120 | if (Proto->isBinaryOp()) | 
|  | 1121 | BinopPrecedence.erase(Proto->getOperatorName()); | 
|  | 1122 | return nullptr; | 
|  | 1123 | } | 
|  | 1124 |  | 
|  | 1125 | //===----------------------------------------------------------------------===// | 
|  | 1126 | // Top-Level parsing and JIT Driver | 
|  | 1127 | //===----------------------------------------------------------------------===// | 
|  | 1128 |  | 
|  | 1129 | static std::unique_ptr<llvm::Module> IRGen(SessionContext &S, | 
|  | 1130 | const FunctionAST &F) { | 
|  | 1131 | IRGenContext C(S); | 
|  | 1132 | auto LF = F.IRGen(C); | 
|  | 1133 | if (!LF) | 
|  | 1134 | return nullptr; | 
|  | 1135 | #ifndef MINIMAL_STDERR_OUTPUT | 
|  | 1136 | fprintf(stderr, "Read function definition:"); | 
|  | 1137 | LF->dump(); | 
|  | 1138 | #endif | 
|  | 1139 | return C.takeM(); | 
|  | 1140 | } | 
|  | 1141 |  | 
|  | 1142 |  | 
|  | 1143 | static void EarthShatteringKaboom() { | 
|  | 1144 | fprintf(stderr, "Earth shattering kaboom."); | 
|  | 1145 | exit(1); | 
|  | 1146 | } | 
|  | 1147 |  | 
|  | 1148 | class KaleidoscopeJIT { | 
|  | 1149 | public: | 
|  | 1150 | typedef ObjectLinkingLayer<> ObjLayerT; | 
|  | 1151 | typedef IRCompileLayer<ObjLayerT> CompileLayerT; | 
|  | 1152 | typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT; | 
|  | 1153 |  | 
|  | 1154 | typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT; | 
|  | 1155 |  | 
|  | 1156 | std::string Mangle(const std::string &Name) { | 
|  | 1157 | std::string MangledName; | 
|  | 1158 | { | 
|  | 1159 | raw_string_ostream MangledNameStream(MangledName); | 
|  | 1160 | Mang.getNameWithPrefix(MangledNameStream, Name); | 
|  | 1161 | } | 
|  | 1162 | return MangledName; | 
|  | 1163 | } | 
|  | 1164 |  | 
|  | 1165 | KaleidoscopeJIT(SessionContext &Session) | 
|  | 1166 | : TM(EngineBuilder().selectTarget()), | 
|  | 1167 | Mang(TM->getDataLayout()), Session(Session), | 
|  | 1168 | ObjectLayer( | 
|  | 1169 | [](){ return llvm::make_unique<SectionMemoryManager>(); }), | 
|  | 1170 | CompileLayer(ObjectLayer, SimpleCompiler(*TM)), | 
|  | 1171 | LazyEmitLayer(CompileLayer), | 
|  | 1172 | CompileCallbacks(LazyEmitLayer, Session.getLLVMContext(), | 
|  | 1173 | reinterpret_cast<uintptr_t>(EarthShatteringKaboom), | 
|  | 1174 | 64) {} | 
|  | 1175 |  | 
|  | 1176 | ModuleHandleT addModule(std::unique_ptr<Module> M) { | 
|  | 1177 | if (!M->getDataLayout()) | 
|  | 1178 | M->setDataLayout(TM->getDataLayout()); | 
|  | 1179 |  | 
|  | 1180 | // The LazyEmitLayer takes lists of modules, rather than single modules, so | 
|  | 1181 | // we'll just build a single-element list. | 
|  | 1182 | std::vector<std::unique_ptr<Module>> S; | 
|  | 1183 | S.push_back(std::move(M)); | 
|  | 1184 |  | 
|  | 1185 | // We need a memory manager to allocate memory and resolve symbols for this | 
|  | 1186 | // new module. Create one that resolves symbols by looking back into the JIT. | 
|  | 1187 | auto MM = createLookasideRTDyldMM<SectionMemoryManager>( | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1188 | [&](const std::string &Name) { | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1189 | // First try to find 'Name' within the JIT. | 
|  | 1190 | if (auto Symbol = findMangledSymbol(Name)) | 
|  | 1191 | return Symbol.getAddress(); | 
|  | 1192 |  | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1193 | // If we don't already have a definition of 'Name' then search | 
|  | 1194 | // the ASTs. | 
|  | 1195 | return searchUncompiledASTs(Name); | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1196 | }, | 
|  | 1197 | [](const std::string &S) { return 0; } ); | 
|  | 1198 |  | 
|  | 1199 | return LazyEmitLayer.addModuleSet(std::move(S), std::move(MM)); | 
|  | 1200 | } | 
|  | 1201 |  | 
|  | 1202 | void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); } | 
|  | 1203 |  | 
|  | 1204 | JITSymbol findMangledSymbol(const std::string &Name) { | 
|  | 1205 | return LazyEmitLayer.findSymbol(Name, true); | 
|  | 1206 | } | 
|  | 1207 |  | 
|  | 1208 | JITSymbol findSymbol(const std::string &Name) { | 
|  | 1209 | return findMangledSymbol(Mangle(Name)); | 
|  | 1210 | } | 
|  | 1211 |  | 
|  | 1212 | JITSymbol findMangledSymbolIn(LazyEmitLayerT::ModuleSetHandleT H, | 
|  | 1213 | const std::string &Name) { | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1214 | return LazyEmitLayer.findSymbolIn(H, Name, true); | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1215 | } | 
|  | 1216 |  | 
|  | 1217 | JITSymbol findSymbolIn(LazyEmitLayerT::ModuleSetHandleT H, | 
|  | 1218 | const std::string &Name) { | 
|  | 1219 | return findMangledSymbolIn(H, Mangle(Name)); | 
|  | 1220 | } | 
|  | 1221 |  | 
|  | 1222 | void addFunctionDefinition(std::unique_ptr<FunctionAST> FnAST) { | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1223 | FunctionDefs[Mangle(FnAST->Proto->Name)] = std::move(FnAST); | 
|  | 1224 | } | 
|  | 1225 |  | 
|  | 1226 | private: | 
|  | 1227 |  | 
|  | 1228 | // This method searches the FunctionDefs map for a definition of 'Name'. If it | 
|  | 1229 | // finds one it generates a stub for it and returns the address of the stub. | 
|  | 1230 | TargetAddress searchUncompiledASTs(const std::string &Name) { | 
|  | 1231 | auto DefI = FunctionDefs.find(Name); | 
|  | 1232 | if (DefI == FunctionDefs.end()) | 
|  | 1233 | return 0; | 
|  | 1234 |  | 
|  | 1235 | // We have AST for 'Name'. IRGen a stub for it and add it to the JIT. | 
|  | 1236 | // FIXME: What happens if IRGen fails? | 
|  | 1237 | auto H = irGenStub(std::move(DefI->second)); | 
|  | 1238 |  | 
|  | 1239 | // Remove the map entry now that we're done with it. | 
| Lang Hames | 193504a | 2015-02-23 04:34:43 +0000 | [diff] [blame^] | 1240 | FunctionDefs.erase(DefI); | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1241 |  | 
|  | 1242 | // Return the address of the stub. | 
|  | 1243 | return findMangledSymbolIn(H, Name).getAddress(); | 
|  | 1244 | } | 
|  | 1245 |  | 
|  | 1246 | // This method will take the AST for a function definition and IR-gen a stub | 
| Lang Hames | c6ba0bf | 2015-02-19 05:33:30 +0000 | [diff] [blame] | 1247 | // for that function that will, on first call, IR-gen the actual body of the | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1248 | // function. | 
|  | 1249 | ModuleHandleT irGenStub(std::unique_ptr<FunctionAST> FnAST) { | 
|  | 1250 | // Step 1) IRGen a prototype for the stub. This will have the same type as | 
|  | 1251 | //         the function. | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1252 | IRGenContext C(Session); | 
|  | 1253 | Function *F = FnAST->Proto->IRGen(C); | 
|  | 1254 | C.getM().setDataLayout(TM->getDataLayout()); | 
|  | 1255 |  | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1256 | // Step 2) Get a compile callback that can be used to compile the body of | 
|  | 1257 | //         the function. The resulting CallbackInfo type will let us set the | 
|  | 1258 | //         compile and update actions for the callback, and get a pointer to | 
|  | 1259 | //         the jit trampoline that we need to call to trigger those actions. | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1260 | auto CallbackInfo = | 
|  | 1261 | CompileCallbacks.getCompileCallback(*F->getFunctionType()); | 
|  | 1262 |  | 
|  | 1263 | // Step 3) Create a stub that will indirectly call the body of this | 
| Lang Hames | 9cebeb6 | 2015-02-17 05:53:28 +0000 | [diff] [blame] | 1264 | //         function once it is compiled. Initially, set the function | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1265 | //         pointer for the indirection to point at the trampoline. | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1266 | std::string BodyPtrName = (F->getName() + "$address").str(); | 
|  | 1267 | GlobalVariable *FunctionBodyPointer = | 
|  | 1268 | createImplPointer(*F, BodyPtrName, CallbackInfo.getAddress()); | 
|  | 1269 | makeStub(*F, *FunctionBodyPointer); | 
|  | 1270 |  | 
| Lang Hames | 9cebeb6 | 2015-02-17 05:53:28 +0000 | [diff] [blame] | 1271 | // Step 4) Add the module containing the stub to the JIT. | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1272 | auto H = addModule(C.takeM()); | 
|  | 1273 |  | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1274 | // Step 5) Set the compile and update actions. | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1275 | // | 
| Lang Hames | fb605d2 | 2015-02-18 23:16:09 +0000 | [diff] [blame] | 1276 | //   The compile action will IRGen the function and add it to the JIT, then | 
|  | 1277 | // request its address, which will trigger codegen. Since we don't need the | 
|  | 1278 | // AST after this, we pass ownership of the AST into the compile action: | 
|  | 1279 | // compile actions (and update actions) are deleted after they're run, so | 
|  | 1280 | // this will free the AST for us. | 
|  | 1281 | // | 
|  | 1282 | //   The update action will update FunctionBodyPointer to point at the newly | 
|  | 1283 | // compiled function. | 
| David Blaikie | 8d2d6b1 | 2015-02-19 19:06:04 +0000 | [diff] [blame] | 1284 | std::shared_ptr<FunctionAST> Fn = std::move(FnAST); | 
|  | 1285 | CallbackInfo.setCompileAction([this, Fn]() { | 
|  | 1286 | auto H = addModule(IRGen(Session, *Fn)); | 
|  | 1287 | return findSymbolIn(H, Fn->Proto->Name).getAddress(); | 
|  | 1288 | }); | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1289 | CallbackInfo.setUpdateAction( | 
| Lang Hames | 2448f48 | 2015-02-18 23:07:13 +0000 | [diff] [blame] | 1290 | CompileCallbacks.getLocalFPUpdater(H, Mangle(BodyPtrName))); | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1291 |  | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1292 | return H; | 
|  | 1293 | } | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1294 |  | 
|  | 1295 | std::unique_ptr<TargetMachine> TM; | 
|  | 1296 | Mangler Mang; | 
|  | 1297 | SessionContext &Session; | 
|  | 1298 |  | 
|  | 1299 | ObjLayerT ObjectLayer; | 
|  | 1300 | CompileLayerT CompileLayer; | 
|  | 1301 | LazyEmitLayerT LazyEmitLayer; | 
|  | 1302 |  | 
|  | 1303 | JITCompileCallbackManager<LazyEmitLayerT, OrcX86_64> CompileCallbacks; | 
| Lang Hames | 56678fe | 2015-02-19 01:32:43 +0000 | [diff] [blame] | 1304 |  | 
|  | 1305 | std::map<std::string, std::unique_ptr<FunctionAST>> FunctionDefs; | 
| Lang Hames | 9b4b92b | 2015-02-17 05:40:42 +0000 | [diff] [blame] | 1306 | }; | 
|  | 1307 |  | 
|  | 1308 | static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) { | 
|  | 1309 | if (auto F = ParseDefinition()) { | 
|  | 1310 | S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto)); | 
|  | 1311 | J.addFunctionDefinition(std::move(F)); | 
|  | 1312 | } else { | 
|  | 1313 | // Skip token for error recovery. | 
|  | 1314 | getNextToken(); | 
|  | 1315 | } | 
|  | 1316 | } | 
|  | 1317 |  | 
|  | 1318 | static void HandleExtern(SessionContext &S) { | 
|  | 1319 | if (auto P = ParseExtern()) | 
|  | 1320 | S.addPrototypeAST(std::move(P)); | 
|  | 1321 | else { | 
|  | 1322 | // Skip token for error recovery. | 
|  | 1323 | getNextToken(); | 
|  | 1324 | } | 
|  | 1325 | } | 
|  | 1326 |  | 
|  | 1327 | static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { | 
|  | 1328 | // Evaluate a top-level expression into an anonymous function. | 
|  | 1329 | if (auto F = ParseTopLevelExpr()) { | 
|  | 1330 | IRGenContext C(S); | 
|  | 1331 | if (auto ExprFunc = F->IRGen(C)) { | 
|  | 1332 | #ifndef MINIMAL_STDERR_OUTPUT | 
|  | 1333 | std::cerr << "Expression function:\n"; | 
|  | 1334 | ExprFunc->dump(); | 
|  | 1335 | #endif | 
|  | 1336 | // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove | 
|  | 1337 | // this module as soon as we've executed Function ExprFunc. | 
|  | 1338 | auto H = J.addModule(C.takeM()); | 
|  | 1339 |  | 
|  | 1340 | // Get the address of the JIT'd function in memory. | 
|  | 1341 | auto ExprSymbol = J.findSymbol("__anon_expr"); | 
|  | 1342 |  | 
|  | 1343 | // Cast it to the right type (takes no arguments, returns a double) so we | 
|  | 1344 | // can call it as a native function. | 
|  | 1345 | double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); | 
|  | 1346 | #ifdef MINIMAL_STDERR_OUTPUT | 
|  | 1347 | FP(); | 
|  | 1348 | #else | 
|  | 1349 | std::cerr << "Evaluated to " << FP() << "\n"; | 
|  | 1350 | #endif | 
|  | 1351 |  | 
|  | 1352 | // Remove the function. | 
|  | 1353 | J.removeModule(H); | 
|  | 1354 | } | 
|  | 1355 | } else { | 
|  | 1356 | // Skip token for error recovery. | 
|  | 1357 | getNextToken(); | 
|  | 1358 | } | 
|  | 1359 | } | 
|  | 1360 |  | 
|  | 1361 | /// top ::= definition | external | expression | ';' | 
|  | 1362 | static void MainLoop() { | 
|  | 1363 | SessionContext S(getGlobalContext()); | 
|  | 1364 | KaleidoscopeJIT J(S); | 
|  | 1365 |  | 
|  | 1366 | while (1) { | 
|  | 1367 | switch (CurTok) { | 
|  | 1368 | case tok_eof:    return; | 
|  | 1369 | case ';':        getNextToken(); continue;  // ignore top-level semicolons. | 
|  | 1370 | case tok_def:    HandleDefinition(S, J); break; | 
|  | 1371 | case tok_extern: HandleExtern(S); break; | 
|  | 1372 | default:         HandleTopLevelExpression(S, J); break; | 
|  | 1373 | } | 
|  | 1374 | #ifndef MINIMAL_STDERR_OUTPUT | 
|  | 1375 | std::cerr << "ready> "; | 
|  | 1376 | #endif | 
|  | 1377 | } | 
|  | 1378 | } | 
|  | 1379 |  | 
|  | 1380 | //===----------------------------------------------------------------------===// | 
|  | 1381 | // "Library" functions that can be "extern'd" from user code. | 
|  | 1382 | //===----------------------------------------------------------------------===// | 
|  | 1383 |  | 
|  | 1384 | /// putchard - putchar that takes a double and returns 0. | 
|  | 1385 | extern "C" | 
|  | 1386 | double putchard(double X) { | 
|  | 1387 | putchar((char)X); | 
|  | 1388 | return 0; | 
|  | 1389 | } | 
|  | 1390 |  | 
|  | 1391 | /// printd - printf that takes a double prints it as "%f\n", returning 0. | 
|  | 1392 | extern "C" | 
|  | 1393 | double printd(double X) { | 
|  | 1394 | printf("%f", X); | 
|  | 1395 | return 0; | 
|  | 1396 | } | 
|  | 1397 |  | 
|  | 1398 | extern "C" | 
|  | 1399 | double printlf() { | 
|  | 1400 | printf("\n"); | 
|  | 1401 | return 0; | 
|  | 1402 | } | 
|  | 1403 |  | 
|  | 1404 | //===----------------------------------------------------------------------===// | 
|  | 1405 | // Main driver code. | 
|  | 1406 | //===----------------------------------------------------------------------===// | 
|  | 1407 |  | 
|  | 1408 | int main() { | 
|  | 1409 | InitializeNativeTarget(); | 
|  | 1410 | InitializeNativeTargetAsmPrinter(); | 
|  | 1411 | InitializeNativeTargetAsmParser(); | 
|  | 1412 |  | 
|  | 1413 | // Install standard binary operators. | 
|  | 1414 | // 1 is lowest precedence. | 
|  | 1415 | BinopPrecedence['='] = 2; | 
|  | 1416 | BinopPrecedence['<'] = 10; | 
|  | 1417 | BinopPrecedence['+'] = 20; | 
|  | 1418 | BinopPrecedence['-'] = 20; | 
|  | 1419 | BinopPrecedence['/'] = 40; | 
|  | 1420 | BinopPrecedence['*'] = 40;  // highest. | 
|  | 1421 |  | 
|  | 1422 | // Prime the first token. | 
|  | 1423 | #ifndef MINIMAL_STDERR_OUTPUT | 
|  | 1424 | std::cerr << "ready> "; | 
|  | 1425 | #endif | 
|  | 1426 | getNextToken(); | 
|  | 1427 |  | 
|  | 1428 | std::cerr << std::fixed; | 
|  | 1429 |  | 
|  | 1430 | // Run the main "interpreter loop" now. | 
|  | 1431 | MainLoop(); | 
|  | 1432 |  | 
|  | 1433 | return 0; | 
|  | 1434 | } | 
|  | 1435 |  |