href="../ProgrammersManual.html#ViewGraph">a window will pop up</a> and you'll
see this graph:</p>
-<center><img src="LangImpl5-cfg.png" alt="Example CFG" width="423"
-height="315"></center>
+<div style="text-align: center"><img src="LangImpl5-cfg.png" alt="Example CFG" width="423"
+height="315"></div>
<p>Another way to get this is to call "<tt>F->viewCFG()</tt>" or
"<tt>F->viewCFGOnly()</tt>" (where F is a "<tt>Function*</tt>") either by
// 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");
</pre>
</div>
// 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);
</pre>
<p>Once the blocks are created, we can emit the conditional branch that chooses
between them. Note that creating new blocks does not implicitly affect the
-LLVMBuilder, so it is still inserting into the block that the condition
+IRBuilder, so it is still inserting into the block that the condition
went into. Also note that it is creating a branch to the "then" block and the
"else" block, even though the "else" block isn't inserted into the function yet.
This is all ok: it is the standard way that LLVM supports forward
// 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()),
+ "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
loop: ; preds = %loop, %entry
%i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
; body
- %calltmp = call double @putchard( double 4.200000e+01 )
+ %calltmp = call double @putchard(double 4.200000e+01)
; increment
- %nextvar = add double %i, 1.000000e+00
+ %nextvar = fadd double %i, 1.000000e+00
; termination test
%cmptmp = fcmp ult double %i, %n
// 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()), VarName.c_str());
Variable->addIncoming(StartVal, PreheaderBB);
</pre>
</div>
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");
// 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");
</pre>
</div>
<pre>
// 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);
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::DoubleTy);
+ return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
}
</pre>
</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/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>
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();
};
/// 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;
//===----------------------------------------------------------------------===//
/// 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 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() {
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");
}
}
// 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()),
+ "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()), 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");
// 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.
return 0;
// 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()));
+ // 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();
+
return 0;
}
</pre>
</div>
+<a href="LangImpl6.html">Next: Extending the language: user-defined operators</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>