diff options
Diffstat (limited to 'docs/tutorial/LangImpl4.html')
-rw-r--r-- | docs/tutorial/LangImpl4.html | 165 |
1 files changed, 90 insertions, 75 deletions
diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html index 9a3bfd2..3188135 100644 --- a/docs/tutorial/LangImpl4.html +++ b/docs/tutorial/LangImpl4.html @@ -171,26 +171,30 @@ add a set of optimizations to run. The code looks like this:</p> <div class="doc_code"> <pre> - 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(); + ExistingModuleProvider *OurModuleProvider = + new ExistingModuleProvider(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()); + + OurFPM.doInitialization(); + + // Set the global so the code gen can use this. + TheFPM = &OurFPM; + + // Run the main "interpreter loop" now. + MainLoop(); </pre> </div> @@ -205,7 +209,7 @@ requires a pointer to the <tt>Module</tt> (through the <tt>ModuleProvider</tt>) to construct itself. Once it is set up, we use a series of "add" calls to add a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass so that later optimizations know how the data structures in the program are -layed out. The "<tt>TheExecutionEngine</tt>" variable is related to the JIT, +laid out. The "<tt>TheExecutionEngine</tt>" variable is related to the JIT, which we will get to in the next section.</p> <p>In this case, we choose to add 4 optimization passes. The passes we chose @@ -298,8 +302,8 @@ by adding a global variable and a call in <tt>main</tt>:</p> ... int main() { .. - <b>// Create the JIT. - TheExecutionEngine = ExecutionEngine::create(TheModule);</b> + <b>// Create the JIT. This takes ownership of the module and module provider. + TheExecutionEngine = EngineBuilder(OurModuleProvider).create();</b> .. } </pre> @@ -320,7 +324,7 @@ top-level expression to look like this:</p> <div class="doc_code"> <pre> 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()) { LF->dump(); // Dump the function for exposition purposes. @@ -330,7 +334,7 @@ static void HandleTopLevelExpression() { // 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());</b> } </pre> @@ -359,7 +363,7 @@ entry: <p>Well this looks like it is basically working. The dump of the function shows the "no argument function that always returns double" that we synthesize -for each top level expression that is typed in. This demonstrates very basic +for each top-level expression that is typed in. This demonstrates very basic functionality, but can we do more?</p> <div class="doc_code"> @@ -495,7 +499,7 @@ LLVM JIT and optimizer. To build this example, use: <div class="doc_code"> <pre> # Compile - g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy + g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit interpreter native` -O3 -o toy # Run ./toy </pre> @@ -512,11 +516,15 @@ at runtime.</p> <pre> #include "llvm/DerivedTypes.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/Interpreter.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/Target/TargetData.h" +#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" #include <cstdio> @@ -538,7 +546,7 @@ enum Token { tok_def = -2, tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5, + tok_identifier = -4, tok_number = -5 }; static std::string IdentifierStr; // Filled in if tok_identifier @@ -640,7 +648,8 @@ public: }; /// 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). class PrototypeAST { std::string Name; std::vector<std::string> Args; @@ -667,7 +676,7 @@ public: //===----------------------------------------------------------------------===// /// 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() { @@ -715,9 +724,9 @@ static ExprAST *ParseIdentifierExpr() { ExprAST *Arg = ParseExpression(); if (!Arg) return 0; Args.push_back(Arg); - + if (CurTok == ')') break; - + if (CurTok != ',') return Error("Expected ')' or ',' in argument list"); getNextToken(); @@ -861,14 +870,14 @@ static PrototypeAST *ParseExtern() { //===----------------------------------------------------------------------===// static Module *TheModule; -static IRBuilder<> 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(APFloat(Val)); + return ConstantFP::get(getGlobalContext(), APFloat(Val)); } Value *VariableExprAST::Codegen() { @@ -889,7 +898,8 @@ Value *BinaryExprAST::Codegen() { case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 - return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp"); + return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), + "booltmp"); default: return ErrorV("invalid binary operator"); } } @@ -915,8 +925,10 @@ Value *CallExprAST::Codegen() { 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 = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); @@ -961,7 +973,7 @@ Function *FunctionAST::Codegen() { return 0; // Create a new basic block to start insertion into. - BasicBlock *BB = BasicBlock::Create("entry", TheFunction); + BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); if (Value *RetVal = Body->Codegen()) { @@ -1013,7 +1025,7 @@ static void HandleExtern() { } 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. @@ -1021,7 +1033,7 @@ static void HandleTopLevelExpression() { // 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 { @@ -1036,7 +1048,7 @@ static void MainLoop() { 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; @@ -1044,8 +1056,6 @@ static void MainLoop() { } } - - //===----------------------------------------------------------------------===// // "Library" functions that can be "extern'd" from user code. //===----------------------------------------------------------------------===// @@ -1062,6 +1072,9 @@ double putchard(double X) { //===----------------------------------------------------------------------===// int main() { + InitializeNativeTarget(); + LLVMContext &Context = getGlobalContext(); + // Install standard binary operators. // 1 is lowest precedence. BinopPrecedence['<'] = 10; @@ -1074,39 +1087,41 @@ int main() { 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); + + ExistingModuleProvider *OurModuleProvider = + new ExistingModuleProvider(TheModule); + + // Create the JIT. This takes ownership of the module and module provider. + TheExecutionEngine = EngineBuilder(OurModuleProvider).create(); + + 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()); + + OurFPM.doInitialization(); + + // Set the global so the code gen can use this. + TheFPM = &OurFPM; + + // Run the main "interpreter loop" now. + MainLoop(); + + TheFPM = 0; + + // Print out all of the generated code. + TheModule->dump(); - { - 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; - - // Print out all of the generated code. - TheModule->dump(); - } // Free module provider (and thus the module) and pass manager. - return 0; } </pre> |