X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2Ftutorial%2FLangImpl4.html;h=8f5e054cec9cf27d16da7b79a22c931a97a7cfa8;hb=04eeefb32a3ae7de4cde1908d30bff61e0d6b86e;hp=378b29b3163dd8b36989b7b9e563c46bcc615ce8;hpb=41fcea3bdb0b05f16bbb6413370079e0d096578e;p=oota-llvm.git diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html index 378b29b3163..8f5e054cec9 100644 --- a/docs/tutorial/LangImpl4.html +++ b/docs/tutorial/LangImpl4.html @@ -56,8 +56,8 @@ Folding

Our demonstration for Chapter 3 is elegant and easy to extend. Unfortunately, -it does not produce wonderful code. For example, when compiling simple code, -we don't get obvious optimizations:

+it does not produce wonderful code. The IRBuilder, however, does give us +obvious optimizations when compiling simple code:

@@ -65,36 +65,14 @@ ready> def test(x) 1+2+x;
 Read function definition:
 define double @test(double %x) {
 entry:
-        %addtmp = add double 1.000000e+00, 2.000000e+00
-        %addtmp1 = add double %addtmp, %x
-        ret double %addtmp1
+        %addtmp = add double 3.000000e+00, %x
+        ret double %addtmp
 }
 
-

This code is a very, very literal transcription of the AST built by parsing -the input. As such, this transcription lacks optimizations like constant folding (we'd like to get "add x, 3.0" in the example above) as well as other more important -optimizations. Constant folding, in particular, is a very common and very -important optimization: so much so that many language implementors implement -constant folding support in their AST representation.

- -

With LLVM, you don't need this support in the AST. Since all calls to build LLVM IR go through -the LLVM builder, it would be nice if the builder itself checked to see if there -was a constant folding opportunity when you call it. If so, it could just do -the constant fold and return the constant instead of creating an instruction. -This is exactly what the LLVMFoldingBuilder class does. Lets make one -change: - -

-
-static LLVMFoldingBuilder Builder;
-
-
- -

All we did was switch from LLVMBuilder to -LLVMFoldingBuilder. Though we change no other code, we now have all of our -instructions implicitly constant folded without us having to do anything -about it. For example, the input above now compiles to:

+

This code is not a literal transcription of the AST built by parsing the +input. That would be:

@@ -102,20 +80,30 @@ ready> def test(x) 1+2+x;
 Read function definition:
 define double @test(double %x) {
 entry:
-        %addtmp = add double 3.000000e+00, %x
-        ret double %addtmp
+        %addtmp = add double 2.000000e+00, 1.000000e+00
+        %addtmp1 = add double %addtmp, %x
+        ret double %addtmp1
 }
 
+Constant folding, as seen above, in particular, is a very common and very +important optimization: so much so that many language implementors implement +constant folding support in their AST representation.

+ +

With LLVM, you don't need this support in the AST. Since all calls to build +LLVM IR go through the LLVM IR builder, the builder itself checked to see if +there was a constant folding opportunity when you call it. If so, it just does +the constant fold and return the constant instead of creating an instruction. +

Well, that was easy :). In practice, we recommend always using -LLVMFoldingBuilder when generating code like this. It has no +IRBuilder when generating code like this. It has no "syntactic overhead" for its use (you don't have to uglify your compiler with constant checks everywhere) and it can dramatically reduce the amount of LLVM IR that is generated in some cases (particular for languages with a macro preprocessor or that use a lot of constants).

-

On the other hand, the LLVMFoldingBuilder is limited by the fact +

On the other hand, the IRBuilder is limited by the fact that it does all of its analysis inline with the code as it is built. If you take a slightly more complex example:

@@ -135,7 +123,7 @@ entry:

In this case, the LHS and RHS of the multiplication are the same value. We'd really like to see this generate "tmp = x+3; result = tmp*tmp;" instead -of computing "x*3" twice.

+of computing "x+3" twice.

Unfortunately, no amount of local analysis will be able to detect and correct this. This requires two transformations: reassociation of expressions (to @@ -525,7 +513,7 @@ LLVM JIT and optimizer. To build this example, use: #include "llvm/Analysis/Verifier.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/LLVMBuilder.h" +#include "llvm/Support/IRBuilder.h" #include <cstdio> #include <string> #include <map> @@ -583,7 +571,7 @@ static int gettok() { if (LastChar == '#') { // Comment until end of line. do LastChar = getchar(); - while (LastChar != EOF && LastChar != '\n' & LastChar != '\r'); + while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); if (LastChar != EOF) return gettok(); @@ -726,7 +714,7 @@ static ExprAST *ParseIdentifierExpr() { if (CurTok == ')') break; if (CurTok != ',') - return Error("Expected ')'"); + return Error("Expected ')' or ',' in argument list"); getNextToken(); } } @@ -868,14 +856,14 @@ static PrototypeAST *ParseExtern() { //===----------------------------------------------------------------------===// static Module *TheModule; -static LLVMFoldingBuilder Builder; +static IRBuilder Builder; 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(APFloat(Val)); } Value *VariableExprAST::Codegen() { @@ -925,7 +913,7 @@ Function *PrototypeAST::Codegen() { std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy); FunctionType *FT = FunctionType::get(Type::DoubleTy, 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. @@ -968,7 +956,7 @@ Function *FunctionAST::Codegen() { return 0; // Create a new basic block to start insertion into. - BasicBlock *BB = new BasicBlock("entry", TheFunction); + BasicBlock *BB = BasicBlock::Create("entry", TheFunction); Builder.SetInsertPoint(BB); if (Value *RetVal = Body->Codegen()) { @@ -1109,16 +1097,17 @@ int main() { MainLoop(); TheFPM = 0; - } // Free module provider and pass manager. - + + // Print out all of the generated code. + TheModule->dump(); + } // Free module provider (and thus the module) and pass manager. - // Print out all of the generated code. - TheModule->dump(); return 0; } +Next: Extending the language: control flow