14ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Analysis/Passes.h"
231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/ExecutionEngine/ExecutionEngine.h"
331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/ExecutionEngine/JIT.h"
40a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DataLayout.h"
50a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/DerivedTypes.h"
60a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/IRBuilder.h"
70a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/LLVMContext.h"
80a08460599eed603e469e3e16d0cf6aa33b8ba93Chandler Carruth#include "llvm/IR/Module.h"
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Verifier.h"
1031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include "llvm/PassManager.h"
113e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h"
124ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include "llvm/Transforms/Scalar.h"
13e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype>
1431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <cstdio>
1531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <map>
164ca7e09b7c1e41535f2a1bd86915375d023daf27Chandler Carruth#include <string>
1731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar#include <vector>
1831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarusing namespace llvm;
1931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
2031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
2131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Lexer
2231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
2331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
2431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
2531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// of these for known things.
2631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarenum Token {
2731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  tok_eof = -1,
2831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
2931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // commands
3031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  tok_def = -2, tok_extern = -3,
3131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
3231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // primary
3331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  tok_identifier = -4, tok_number = -5
3431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
3531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
3631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::string IdentifierStr;  // Filled in if tok_identifier
3731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic double NumVal;              // Filled in if tok_number
3831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
3931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// gettok - Return the next token from standard input.
4031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int gettok() {
4131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  static int LastChar = ' ';
4231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
4331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Skip any whitespace.
4431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  while (isspace(LastChar))
4531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    LastChar = getchar();
4631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
4731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
4831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    IdentifierStr = LastChar;
4931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    while (isalnum((LastChar = getchar())))
5031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      IdentifierStr += LastChar;
5131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
5231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (IdentifierStr == "def") return tok_def;
5331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (IdentifierStr == "extern") return tok_extern;
5431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return tok_identifier;
5531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
5631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
5731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
5831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    std::string NumStr;
5931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    do {
6031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      NumStr += LastChar;
6131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      LastChar = getchar();
6231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    } while (isdigit(LastChar) || LastChar == '.');
6331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
6431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    NumVal = strtod(NumStr.c_str(), 0);
6531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return tok_number;
6631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
6731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
6831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (LastChar == '#') {
6931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Comment until end of line.
7031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    do LastChar = getchar();
7131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
7231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
7331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (LastChar != EOF)
7431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      return gettok();
7531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
7631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
7731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Check for end of file.  Don't eat the EOF.
7831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (LastChar == EOF)
7931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return tok_eof;
8031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
8131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Otherwise, just return the character as its ascii value.
8231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  int ThisChar = LastChar;
8331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  LastChar = getchar();
8431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return ThisChar;
8531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
8631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
8731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
8831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Abstract Syntax Tree (aka Parse Tree)
8931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
909d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendlingnamespace {
9131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// ExprAST - Base class for all expression nodes.
9231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass ExprAST {
9331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
949d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling  virtual ~ExprAST() {}
9531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  virtual Value *Codegen() = 0;
9631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
9731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
9831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// NumberExprAST - Expression class for numeric literals like "1.0".
9931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass NumberExprAST : public ExprAST {
10031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  double Val;
10131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
10231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  NumberExprAST(double val) : Val(val) {}
10331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  virtual Value *Codegen();
10431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
10531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
10631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// VariableExprAST - Expression class for referencing a variable, like "a".
10731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass VariableExprAST : public ExprAST {
10831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::string Name;
10931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
11031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  VariableExprAST(const std::string &name) : Name(name) {}
11131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  virtual Value *Codegen();
11231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
11331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
11431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// BinaryExprAST - Expression class for a binary operator.
11531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass BinaryExprAST : public ExprAST {
11631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  char Op;
11731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  ExprAST *LHS, *RHS;
11831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
11931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
12031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    : Op(op), LHS(lhs), RHS(rhs) {}
12131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  virtual Value *Codegen();
12231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
12331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
12431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// CallExprAST - Expression class for function calls.
12531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass CallExprAST : public ExprAST {
12631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::string Callee;
12731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::vector<ExprAST*> Args;
12831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
12931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
13031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    : Callee(callee), Args(args) {}
13131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  virtual Value *Codegen();
13231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
13331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
13431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// PrototypeAST - This class represents the "prototype" for a function,
13531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// which captures its name, and its argument names (thus implicitly the number
13631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// of arguments the function takes).
13731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass PrototypeAST {
13831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::string Name;
13931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::vector<std::string> Args;
14031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
14131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  PrototypeAST(const std::string &name, const std::vector<std::string> &args)
14231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    : Name(name), Args(args) {}
14331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
14431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Function *Codegen();
14531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
14631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
14731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// FunctionAST - This class represents a function definition itself.
14831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarclass FunctionAST {
14931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  PrototypeAST *Proto;
15031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  ExprAST *Body;
15131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarpublic:
15231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  FunctionAST(PrototypeAST *proto, ExprAST *body)
15331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    : Proto(proto), Body(body) {}
15431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
15531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Function *Codegen();
15631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar};
1579d7c776d32c8a4d64b37a91c2d627629cf1498efBill Wendling} // end anonymous namespace
15831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
15931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
16031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Parser
16131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
16231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
16331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
16431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// token the parser is looking at.  getNextToken reads another token from the
16531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// lexer and updates CurTok with its results.
16631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int CurTok;
16731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int getNextToken() {
16831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return CurTok = gettok();
16931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
17031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
17131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// BinopPrecedence - This holds the precedence for each binary operator that is
17231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// defined.
17331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::map<char, int> BinopPrecedence;
17431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
17531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// GetTokPrecedence - Get the precedence of the pending binary operator token.
17631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic int GetTokPrecedence() {
17731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (!isascii(CurTok))
17831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return -1;
17931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
18031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Make sure it's a declared binop.
18131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  int TokPrec = BinopPrecedence[CurTok];
18231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (TokPrec <= 0) return -1;
18331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return TokPrec;
18431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
18531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
18631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// Error* - These are little helper functions for error handling.
18731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
18831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarPrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
18931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
19031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
19131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseExpression();
19231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
19331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// identifierexpr
19431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= identifier
19531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= identifier '(' expression* ')'
19631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseIdentifierExpr() {
19731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::string IdName = IdentifierStr;
19831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
19931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat identifier.
20031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
20131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != '(') // Simple variable ref.
20231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return new VariableExprAST(IdName);
20331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
20431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Call.
20531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat (
20631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::vector<ExprAST*> Args;
20731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != ')') {
20831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    while (1) {
20931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      ExprAST *Arg = ParseExpression();
21031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      if (!Arg) return 0;
21131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      Args.push_back(Arg);
21231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
21331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      if (CurTok == ')') break;
21431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
21531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      if (CurTok != ',')
21631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar        return Error("Expected ')' or ',' in argument list");
21731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      getNextToken();
21831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
21931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
22031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
22131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Eat the ')'.
22231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();
22331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
22431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return new CallExprAST(IdName, Args);
22531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
22631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
22731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// numberexpr ::= number
22831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseNumberExpr() {
22931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  ExprAST *Result = new NumberExprAST(NumVal);
23031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken(); // consume the number
23131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return Result;
23231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
23331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
23431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// parenexpr ::= '(' expression ')'
23531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseParenExpr() {
23631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat (.
23731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  ExprAST *V = ParseExpression();
23831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (!V) return 0;
23931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
24031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != ')')
24131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return Error("expected ')'");
24231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat ).
24331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return V;
24431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
24531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
24631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// primary
24731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= identifierexpr
24831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= numberexpr
24931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= parenexpr
25031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParsePrimary() {
25131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  switch (CurTok) {
25231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  default: return Error("unknown token when expecting an expression");
25331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  case tok_identifier: return ParseIdentifierExpr();
25431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  case tok_number:     return ParseNumberExpr();
25531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  case '(':            return ParseParenExpr();
25631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
25731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
25831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
25931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// binoprhs
26031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= ('+' primary)*
26131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
26231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // If this is a binop, find its precedence.
26331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  while (1) {
26431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    int TokPrec = GetTokPrecedence();
26531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
26631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // If this is a binop that binds at least as tightly as the current binop,
26731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // consume it, otherwise we are done.
26831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (TokPrec < ExprPrec)
26931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      return LHS;
27031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
27131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Okay, we know this is a binop.
27231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    int BinOp = CurTok;
27331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    getNextToken();  // eat binop
27431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
27531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Parse the primary expression after the binary operator.
27631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    ExprAST *RHS = ParsePrimary();
27731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (!RHS) return 0;
27831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
27931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // If BinOp binds less tightly with RHS than the operator after RHS, let
28031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // the pending operator take RHS as its LHS.
28131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    int NextPrec = GetTokPrecedence();
28231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (TokPrec < NextPrec) {
28331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      RHS = ParseBinOpRHS(TokPrec+1, RHS);
28431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      if (RHS == 0) return 0;
28531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
28631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
28731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Merge LHS/RHS.
28831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    LHS = new BinaryExprAST(BinOp, LHS, RHS);
28931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
29031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
29131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
29231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// expression
29331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= primary binoprhs
29431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///
29531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExprAST *ParseExpression() {
29631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  ExprAST *LHS = ParsePrimary();
29731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (!LHS) return 0;
29831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
29931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return ParseBinOpRHS(0, LHS);
30031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
30131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
30231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// prototype
30331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar///   ::= id '(' id* ')'
30431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic PrototypeAST *ParsePrototype() {
30531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != tok_identifier)
30631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return ErrorP("Expected function name in prototype");
30731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
30831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::string FnName = IdentifierStr;
30931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();
31031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
31131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != '(')
31231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return ErrorP("Expected '(' in prototype");
31331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
31431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::vector<std::string> ArgNames;
31531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  while (getNextToken() == tok_identifier)
31631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    ArgNames.push_back(IdentifierStr);
31731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CurTok != ')')
31831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return ErrorP("Expected ')' in prototype");
31931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
32031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // success.
32131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat ')'.
32231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
32331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return new PrototypeAST(FnName, ArgNames);
32431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
32531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
32631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// definition ::= 'def' prototype expression
32731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionAST *ParseDefinition() {
32831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat def.
32931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  PrototypeAST *Proto = ParsePrototype();
33031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (Proto == 0) return 0;
33131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
33231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (ExprAST *E = ParseExpression())
33331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return new FunctionAST(Proto, E);
33431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return 0;
33531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
33631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
33731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// toplevelexpr ::= expression
33831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionAST *ParseTopLevelExpr() {
33931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (ExprAST *E = ParseExpression()) {
34031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Make an anonymous proto.
34131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
34231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return new FunctionAST(Proto, E);
34331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
34431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return 0;
34531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
34631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
34731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// external ::= 'extern' prototype
34831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic PrototypeAST *ParseExtern() {
34931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();  // eat extern.
35031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return ParsePrototype();
35131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
35231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
35331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
35431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Code Generation
35531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
35631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
35731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic Module *TheModule;
35831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic IRBuilder<> Builder(getGlobalContext());
35931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic std::map<std::string, Value*> NamedValues;
36031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic FunctionPassManager *TheFPM;
36131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
36231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *ErrorV(const char *Str) { Error(Str); return 0; }
36331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
36431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *NumberExprAST::Codegen() {
36531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return ConstantFP::get(getGlobalContext(), APFloat(Val));
36631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
36731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
36831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *VariableExprAST::Codegen() {
36931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Look this variable up in the function.
37031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Value *V = NamedValues[Name];
37131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return V ? V : ErrorV("Unknown variable name");
37231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
37331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
37431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *BinaryExprAST::Codegen() {
37531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Value *L = LHS->Codegen();
37631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Value *R = RHS->Codegen();
37731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (L == 0 || R == 0) return 0;
37831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
37931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  switch (Op) {
3802632bbf0de4637e02f333952991263d526976fafEric Christopher  case '+': return Builder.CreateFAdd(L, R, "addtmp");
3812632bbf0de4637e02f333952991263d526976fafEric Christopher  case '-': return Builder.CreateFSub(L, R, "subtmp");
3822632bbf0de4637e02f333952991263d526976fafEric Christopher  case '*': return Builder.CreateFMul(L, R, "multmp");
38331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  case '<':
38431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    L = Builder.CreateFCmpULT(L, R, "cmptmp");
38531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Convert bool 0/1 to double 0.0 or 1.0
38631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
38731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar                                "booltmp");
38831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  default: return ErrorV("invalid binary operator");
38931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
39031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
39131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
39231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarValue *CallExprAST::Codegen() {
39331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Look up the name in the global module table.
39431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Function *CalleeF = TheModule->getFunction(Callee);
39531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CalleeF == 0)
39631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return ErrorV("Unknown function referenced");
39731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
39831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // If argument mismatch error.
39931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (CalleeF->arg_size() != Args.size())
40031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return ErrorV("Incorrect # arguments passed");
40131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
40231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  std::vector<Value*> ArgsV;
40331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
40431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    ArgsV.push_back(Args[i]->Codegen());
40531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (ArgsV.back() == 0) return 0;
40631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
40731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
4080bd9d3af54b62152355525bea7914bdef4600371Francois Pichet  return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
40931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
41031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
41131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunction *PrototypeAST::Codegen() {
41231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Make the function type:  double(double,double) etc.
413d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley  std::vector<Type*> Doubles(Args.size(),
414d1c2bd8e6e37e08393f7c4980efc5bcb66b6f0d0John Wiegley                             Type::getDoubleTy(getGlobalContext()));
41531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
41631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar                                       Doubles, false);
41731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
41831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
41931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
42031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // If F conflicted, there was already something named 'Name'.  If it has a
42131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // body, don't allow redefinition or reextern.
42231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (F->getName() != Name) {
42331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Delete the one we just made and get the existing one.
42431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    F->eraseFromParent();
42531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    F = TheModule->getFunction(Name);
42631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
42731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // If F already has a body, reject this.
42831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (!F->empty()) {
42931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      ErrorF("redefinition of function");
43031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      return 0;
43131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
43231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
43331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // If F took a different number of args, reject.
43431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (F->arg_size() != Args.size()) {
43531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      ErrorF("redefinition of function with different # args");
43631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      return 0;
43731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
43831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
43931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
44031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Set names for all arguments.
44131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  unsigned Idx = 0;
44231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
44331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar       ++AI, ++Idx) {
44431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    AI->setName(Args[Idx]);
44531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
44631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Add arguments to variable symbol table.
44731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    NamedValues[Args[Idx]] = AI;
44831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
44931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
45031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return F;
45131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
45231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
45331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick TryzelaarFunction *FunctionAST::Codegen() {
45431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  NamedValues.clear();
45531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
45631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Function *TheFunction = Proto->Codegen();
45731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (TheFunction == 0)
45831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return 0;
45931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
46031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Create a new basic block to start insertion into.
46131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
46231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  Builder.SetInsertPoint(BB);
46331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
46431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (Value *RetVal = Body->Codegen()) {
46531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Finish off the function.
46631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    Builder.CreateRet(RetVal);
46731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
46831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Validate the generated code, checking for consistency.
46931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    verifyFunction(*TheFunction);
47031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
47131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Optimize the function.
47231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    TheFPM->run(*TheFunction);
47331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
47431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    return TheFunction;
47531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
47631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
47731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Error reading body, remove function.
47831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  TheFunction->eraseFromParent();
47931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return 0;
48031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
48131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
48231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
48331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Top-Level parsing and JIT Driver
48431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
48531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
48631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic ExecutionEngine *TheExecutionEngine;
48731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
48831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleDefinition() {
48931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (FunctionAST *F = ParseDefinition()) {
49031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (Function *LF = F->Codegen()) {
49131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      fprintf(stderr, "Read function definition:");
49231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      LF->dump();
49331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
49431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  } else {
49531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Skip token for error recovery.
49631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    getNextToken();
49731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
49831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
49931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
50031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleExtern() {
50131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (PrototypeAST *P = ParseExtern()) {
50231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (Function *F = P->Codegen()) {
50331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      fprintf(stderr, "Read extern: ");
50431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      F->dump();
50531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
50631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  } else {
50731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Skip token for error recovery.
50831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    getNextToken();
50931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
51031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
51131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
51231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void HandleTopLevelExpression() {
51331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Evaluate a top-level expression into an anonymous function.
51431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  if (FunctionAST *F = ParseTopLevelExpr()) {
51531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    if (Function *LF = F->Codegen()) {
51631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      // JIT the function, returning a function pointer.
51731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
51831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
51931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      // Cast it to the right type (takes no arguments, returns a double) so we
52031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      // can call it as a native function.
52131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      double (*FP)() = (double (*)())(intptr_t)FPtr;
52231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar      fprintf(stderr, "Evaluated to %f\n", FP());
52331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
52431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  } else {
52531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    // Skip token for error recovery.
52631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    getNextToken();
52731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
52831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
52931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
53031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// top ::= definition | external | expression | ';'
53131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarstatic void MainLoop() {
53231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  while (1) {
53331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    fprintf(stderr, "ready> ");
53431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    switch (CurTok) {
53531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    case tok_eof:    return;
53631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    case ';':        getNextToken(); break;  // ignore top-level semicolons.
53731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    case tok_def:    HandleDefinition(); break;
53831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    case tok_extern: HandleExtern(); break;
53931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    default:         HandleTopLevelExpression(); break;
54031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar    }
54131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  }
54231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
54331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
54431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
54531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// "Library" functions that can be "extern'd" from user code.
54631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
54731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
54831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar/// putchard - putchar that takes a double and returns 0.
54931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarextern "C"
55031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaardouble putchard(double X) {
55131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  putchar((char)X);
55231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return 0;
55331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
55431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
55531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
55631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar// Main driver code.
55731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar//===----------------------------------------------------------------------===//
55831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
55931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaarint main() {
56031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  InitializeNativeTarget();
56131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  LLVMContext &Context = getGlobalContext();
56231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
56331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Install standard binary operators.
56431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // 1 is lowest precedence.
56531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BinopPrecedence['<'] = 10;
56631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BinopPrecedence['+'] = 20;
56731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BinopPrecedence['-'] = 20;
56831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  BinopPrecedence['*'] = 40;  // highest.
56931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
57031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Prime the first token.
57131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  fprintf(stderr, "ready> ");
57231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  getNextToken();
57331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
57431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Make the module, which holds all the code.
57531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  TheModule = new Module("my cool jit", Context);
57631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
577f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  // Create the JIT.  This takes ownership of the module.
57842fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin  std::string ErrStr;
57942fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin  TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
58042fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin  if (!TheExecutionEngine) {
58142fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin    fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
58242fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin    exit(1);
58342fc5586241ddc5948ffff67eefe8cb2690534a8Jeffrey Yasskin  }
58431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
585f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  FunctionPassManager OurFPM(TheModule);
58631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
58731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Set up the optimizer pipeline.  Start with registering info about how the
58831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // target lays out data structures.
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TheModule->setDataLayout(TheExecutionEngine->getDataLayout());
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OurFPM.add(new DataLayoutPass(TheModule));
591dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman  // Provide basic AliasAnalysis support for GVN.
592dfa1a79b0c2f09349b6cd451198781a3ced48cb8Dan Gohman  OurFPM.add(createBasicAliasAnalysisPass());
59331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Do simple "peephole" optimizations and bit-twiddling optzns.
59431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  OurFPM.add(createInstructionCombiningPass());
59531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Reassociate expressions.
59631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  OurFPM.add(createReassociatePass());
59731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Eliminate Common SubExpressions.
59831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  OurFPM.add(createGVNPass());
59931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Simplify the control flow graph (deleting unreachable blocks, etc).
60031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  OurFPM.add(createCFGSimplificationPass());
60131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
60231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  OurFPM.doInitialization();
60331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
60431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Set the global so the code gen can use this.
60531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  TheFPM = &OurFPM;
60631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
60731c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Run the main "interpreter loop" now.
60831c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  MainLoop();
60931c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
61031c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  TheFPM = 0;
61131c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
61231c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  // Print out all of the generated code.
61331c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  TheModule->dump();
61431c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar
61531c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar  return 0;
61631c6c5d58a6d2254063e8a18fd32b851a06e2ddfErick Tryzelaar}
617