static PrototypeAST *ParsePrototype() {
std::string FnName;
- <b>int Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ <b>unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
unsigned BinaryPrecedence = 30;</b>
switch (CurTok) {
if (L == 0 || R == 0) return 0;
switch (Op) {
- case '+': return Builder.CreateAdd(L, R, "addtmp");
- case '-': return Builder.CreateSub(L, R, "subtmp");
- case '*': return Builder.CreateMul(L, R, "multmp");
+ case '+': return Builder.CreateFAdd(L, R, "addtmp");
+ case '-': return Builder.CreateFSub(L, R, "subtmp");
+ case '*': return Builder.CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
+ "booltmp");
<b>default: break;</b>
}
functions (because the "prototype" boils down to a function with the right
name) everything falls into place.</p>
-<p>The final piece of code we are missing, is a bit of top level magic:</p>
+<p>The final piece of code we are missing, is a bit of top-level magic:</p>
<div class="doc_code">
<pre>
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();</b>
// Create a new basic block to start insertion into.
- BasicBlock *BB = new BasicBlock("entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);
if (Value *RetVal = Body->Codegen()) {
static PrototypeAST *ParsePrototype() {
std::string FnName;
- int Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
unsigned BinaryPrecedence = 30;
switch (CurTok) {
def unary-(v)
0-v;
-# Define > with the same precedence as >.
+# Define > with the same precedence as <.
def binary> 10 (LHS RHS)
RHS < LHS;
</div>
-
<!-- *********************************************************************** -->
<div class="doc_section"><a name="code">Full Code Listing</a></div>
<!-- *********************************************************************** -->
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
+#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/LLVMBuilder.h"
+#include "llvm/Support/IRBuilder.h"
#include <cstdio>
#include <string>
#include <map>
};
/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
//===----------------------------------------------------------------------===//
/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
-/// token the parser it looking at. getNextToken reads another token from the
+/// token the parser is looking at. getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
static int getNextToken() {
ExprAST *Arg = ParseExpression();
if (!Arg) return 0;
Args.push_back(Arg);
-
+
if (CurTok == ')') break;
-
+
if (CurTok != ',')
- return Error("Expected ')'");
+ return Error("Expected ')' or ',' in argument list");
getNextToken();
}
}
return new ForExprAST(IdName, Start, End, Step, Body);
}
-
/// primary
/// ::= identifierexpr
/// ::= numberexpr
static PrototypeAST *ParsePrototype() {
std::string FnName;
- int Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
+ unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
unsigned BinaryPrecedence = 30;
switch (CurTok) {
//===----------------------------------------------------------------------===//
static Module *TheModule;
-static LLVMFoldingBuilder Builder;
+static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value*> NamedValues;
static FunctionPassManager *TheFPM;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
Value *NumberExprAST::Codegen() {
- return ConstantFP::get(Type::DoubleTy, APFloat(Val));
+ return ConstantFP::get(getGlobalContext(), APFloat(Val));
}
Value *VariableExprAST::Codegen() {
return Builder.CreateCall(F, OperandV, "unop");
}
-
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0) return 0;
switch (Op) {
- case '+': return Builder.CreateAdd(L, R, "addtmp");
- case '-': return Builder.CreateSub(L, R, "subtmp");
- case '*': return Builder.CreateMul(L, R, "multmp");
+ case '+': return Builder.CreateFAdd(L, R, "addtmp");
+ case '-': return Builder.CreateFSub(L, R, "subtmp");
+ case '*': return Builder.CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
- return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
+ "booltmp");
default: break;
}
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV,
- ConstantFP::get(Type::DoubleTy, APFloat(0.0)),
+ ConstantFP::get(getGlobalContext(), APFloat(0.0)),
"ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB = new BasicBlock("then", TheFunction);
- BasicBlock *ElseBB = new BasicBlock("else");
- BasicBlock *MergeBB = new BasicBlock("ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
+ BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN = Builder.CreatePHI(Type::DoubleTy, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,
+ "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
- BasicBlock *LoopBB = new BasicBlock("loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
- PHINode *Variable = Builder.CreatePHI(Type::DoubleTy, VarName.c_str());
+ PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str());
Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to the PHI node. If it
if (StepVal == 0) return 0;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(Type::DoubleTy, APFloat(1.0));
+ StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
}
- Value *NextVar = Builder.CreateAdd(Variable, StepVal, "nextvar");
+ Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar");
// Compute the end condition.
Value *EndCond = End->Codegen();
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(EndCond,
- ConstantFP::get(Type::DoubleTy, APFloat(0.0)),
+ ConstantFP::get(getGlobalContext(), APFloat(0.0)),
"loopcond");
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
- BasicBlock *AfterBB = new BasicBlock("afterloop", TheFunction);
+ BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::DoubleTy);
+ return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
}
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy);
- FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+ std::vector<const Type*> Doubles(Args.size(),
+ Type::getDoubleTy(getGlobalContext()));
+ FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
+ Doubles, false);
- Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
+ Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
// If F conflicted, there was already something named 'Name'. If it has a
// body, don't allow redefinition or reextern.
BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = new BasicBlock("entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);
if (Value *RetVal = Body->Codegen()) {
}
static void HandleTopLevelExpression() {
- // Evaluate a top level expression into an anonymous function.
+ // Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
// JIT the function, returning a function pointer.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
- double (*FP)() = (double (*)())FPtr;
+ double (*FP)() = (double (*)())(intptr_t)FPtr;
fprintf(stderr, "Evaluated to %f\n", FP());
}
} else {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof: return;
- case ';': getNextToken(); break; // ignore top level semicolons.
+ case ';': getNextToken(); break; // ignore top-level semicolons.
case tok_def: HandleDefinition(); break;
case tok_extern: HandleExtern(); break;
default: HandleTopLevelExpression(); break;
}
}
-
-
//===----------------------------------------------------------------------===//
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
int main() {
+ InitializeNativeTarget();
+ LLVMContext &Context = getGlobalContext();
+
// Install standard binary operators.
// 1 is lowest precedence.
BinopPrecedence['<'] = 10;
getNextToken();
// Make the module, which holds all the code.
- TheModule = new Module("my cool jit");
-
- // Create the JIT.
- TheExecutionEngine = ExecutionEngine::create(TheModule);
+ TheModule = new Module("my cool jit", Context);
+
+ // Create the JIT. This takes ownership of the module.
+ std::string ErrStr;
+ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
+ if (!TheExecutionEngine) {
+ fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
+ exit(1);
+ }
+
+ FunctionPassManager OurFPM(TheModule);
+
+ // Set up the optimizer pipeline. Start with registering info about how the
+ // target lays out data structures.
+ OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ // Provide basic AliasAnalysis support for GVN.
+ OurFPM.add(createBasicAliasAnalysisPass());
+ // Do simple "peephole" optimizations and bit-twiddling optzns.
+ OurFPM.add(createInstructionCombiningPass());
+ // Reassociate expressions.
+ OurFPM.add(createReassociatePass());
+ // Eliminate Common SubExpressions.
+ OurFPM.add(createGVNPass());
+ // Simplify the control flow graph (deleting unreachable blocks, etc).
+ OurFPM.add(createCFGSimplificationPass());
+
+ OurFPM.doInitialization();
+
+ // Set the global so the code gen can use this.
+ TheFPM = &OurFPM;
+
+ // Run the main "interpreter loop" now.
+ MainLoop();
+
+ TheFPM = 0;
- {
- ExistingModuleProvider OurModuleProvider(TheModule);
- FunctionPassManager OurFPM(&OurModuleProvider);
-
- // Set up the optimizer pipeline. Start with registering info about how the
- // target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
- // Do simple "peephole" optimizations and bit-twiddling optzns.
- OurFPM.add(createInstructionCombiningPass());
- // Reassociate expressions.
- OurFPM.add(createReassociatePass());
- // Eliminate Common SubExpressions.
- OurFPM.add(createGVNPass());
- // Simplify the control flow graph (deleting unreachable blocks, etc).
- OurFPM.add(createCFGSimplificationPass());
- // Set the global so the code gen can use this.
- TheFPM = &OurFPM;
-
- // Run the main "interpreter loop" now.
- MainLoop();
-
- TheFPM = 0;
- } // Free module provider and pass manager.
-
-
// Print out all of the generated code.
- TheModule->dump();
+ TheModule->dump();
+
return 0;
}
</pre>
</div>
+<a href="LangImpl7.html">Next: Extending the language: mutable variables / SSA construction</a>
</div>
<!-- *********************************************************************** -->
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date$
</address>
</body>
</html>