136 changes: 72 additions & 64 deletions llvm/examples/Kaleidoscope/Chapter7/toy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,13 +701,14 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//

static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;
static std::map<std::string, AllocaInst *> NamedValues;
static std::unique_ptr<legacy::FunctionPassManager> TheFPM;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
static ExitOnError ExitOnErr;

Value *LogErrorV(const char *Str) {
LogError(Str);
Expand Down Expand Up @@ -735,11 +736,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
StringRef VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, VarName);
}

Value *NumberExprAST::codegen() {
return ConstantFP::get(TheContext, APFloat(Val));
return ConstantFP::get(*TheContext, APFloat(Val));
}

Value *VariableExprAST::codegen() {
Expand All @@ -749,7 +750,7 @@ Value *VariableExprAST::codegen() {
return LogErrorV("Unknown variable name");

// Load the value.
return Builder.CreateLoad(V, Name.c_str());
return Builder->CreateLoad(V, Name.c_str());
}

Value *UnaryExprAST::codegen() {
Expand All @@ -761,7 +762,7 @@ Value *UnaryExprAST::codegen() {
if (!F)
return LogErrorV("Unknown unary operator");

return Builder.CreateCall(F, OperandV, "unop");
return Builder->CreateCall(F, OperandV, "unop");
}

Value *BinaryExprAST::codegen() {
Expand All @@ -784,7 +785,7 @@ Value *BinaryExprAST::codegen() {
if (!Variable)
return LogErrorV("Unknown variable name");

Builder.CreateStore(Val, Variable);
Builder->CreateStore(Val, Variable);
return Val;
}

Expand All @@ -795,15 +796,15 @@ Value *BinaryExprAST::codegen() {

switch (Op) {
case '+':
return Builder.CreateFAdd(L, R, "addtmp");
return Builder->CreateFAdd(L, R, "addtmp");
case '-':
return Builder.CreateFSub(L, R, "subtmp");
return Builder->CreateFSub(L, R, "subtmp");
case '*':
return Builder.CreateFMul(L, R, "multmp");
return Builder->CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
L = Builder->CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
default:
break;
}
Expand All @@ -814,7 +815,7 @@ Value *BinaryExprAST::codegen() {
assert(F && "binary operator not found!");

Value *Ops[] = {L, R};
return Builder.CreateCall(F, Ops, "binop");
return Builder->CreateCall(F, Ops, "binop");
}

Value *CallExprAST::codegen() {
Expand All @@ -834,7 +835,7 @@ Value *CallExprAST::codegen() {
return nullptr;
}

return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
}

Value *IfExprAST::codegen() {
Expand All @@ -843,46 +844,46 @@ Value *IfExprAST::codegen() {
return nullptr;

// Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
CondV = Builder->CreateFCmpONE(
CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond");

Function *TheFunction = Builder.GetInsertBlock()->getParent();
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 = BasicBlock::Create(TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont");

Builder.CreateCondBr(CondV, ThenBB, ElseBB);
Builder->CreateCondBr(CondV, ThenBB, ElseBB);

// Emit then value.
Builder.SetInsertPoint(ThenBB);
Builder->SetInsertPoint(ThenBB);

Value *ThenV = Then->codegen();
if (!ThenV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
ThenBB = Builder.GetInsertBlock();
ThenBB = Builder->GetInsertBlock();

// Emit else block.
TheFunction->getBasicBlockList().push_back(ElseBB);
Builder.SetInsertPoint(ElseBB);
Builder->SetInsertPoint(ElseBB);

Value *ElseV = Else->codegen();
if (!ElseV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
ElseBB = Builder.GetInsertBlock();
ElseBB = Builder->GetInsertBlock();

// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
Builder->SetInsertPoint(MergeBB);
PHINode *PN = Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp");

PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
Expand All @@ -909,7 +910,7 @@ Value *IfExprAST::codegen() {
// br endcond, loop, endloop
// outloop:
Value *ForExprAST::codegen() {
Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Expand All @@ -920,17 +921,17 @@ Value *ForExprAST::codegen() {
return nullptr;

// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
Builder->CreateStore(StartVal, Alloca);

// Make the new basic block for the loop header, inserting after current
// block.
BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "loop", TheFunction);

// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
Builder->CreateBr(LoopBB);

// Start insertion in LoopBB.
Builder.SetInsertPoint(LoopBB);
Builder->SetInsertPoint(LoopBB);

// Within the loop, the variable is defined equal to the PHI node. If it
// shadows an existing variable, we have to restore it, so save it now.
Expand All @@ -951,7 +952,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(TheContext, APFloat(1.0));
StepVal = ConstantFP::get(*TheContext, APFloat(1.0));
}

// Compute the end condition.
Expand All @@ -961,23 +962,23 @@ Value *ForExprAST::codegen() {

// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
Value *CurVar = Builder->CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar");
Builder->CreateStore(NextVar, Alloca);

// Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
EndCond = Builder->CreateFCmpONE(
EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond");

// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
BasicBlock::Create(TheContext, "afterloop", TheFunction);
BasicBlock::Create(*TheContext, "afterloop", TheFunction);

// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
Builder->CreateCondBr(EndCond, LoopBB, AfterBB);

// Any new code will be inserted in AfterBB.
Builder.SetInsertPoint(AfterBB);
Builder->SetInsertPoint(AfterBB);

// Restore the unshadowed variable.
if (OldVal)
Expand All @@ -986,13 +987,13 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);

// for expr always returns 0.0.
return Constant::getNullValue(Type::getDoubleTy(TheContext));
return Constant::getNullValue(Type::getDoubleTy(*TheContext));
}

Value *VarExprAST::codegen() {
std::vector<AllocaInst *> OldBindings;

Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
Expand All @@ -1010,11 +1011,11 @@ Value *VarExprAST::codegen() {
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(TheContext, APFloat(0.0));
InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
}

AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Builder.CreateStore(InitVal, Alloca);
Builder->CreateStore(InitVal, Alloca);

// Remember the old variable binding so that we can restore the binding when
// we unrecurse.
Expand All @@ -1039,9 +1040,9 @@ Value *VarExprAST::codegen() {

Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(*TheContext));
FunctionType *FT =
FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);

Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
Expand All @@ -1068,8 +1069,8 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();

// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
Builder->SetInsertPoint(BB);

// Record the function arguments in the NamedValues map.
NamedValues.clear();
Expand All @@ -1078,15 +1079,15 @@ Function *FunctionAST::codegen() {
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());

// Store the initial value into the alloca.
Builder.CreateStore(&Arg, Alloca);
Builder->CreateStore(&Arg, Alloca);

// Add arguments to variable symbol table.
NamedValues[std::string(Arg.getName())] = Alloca;
}

if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
Builder->CreateRet(RetVal);

// Validate the generated code, checking for consistency.
verifyFunction(*TheFunction);
Expand All @@ -1111,8 +1112,12 @@ Function *FunctionAST::codegen() {

static void InitializeModuleAndPassManager() {
// Open a new module.
TheModule = std::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
TheModule->setDataLayout(TheJIT->getDataLayout());

// Create a new builder for the module.
Builder = std::make_unique<IRBuilder<>>(*TheContext);

// Create a new pass manager attached to it.
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
Expand All @@ -1137,7 +1142,8 @@ static void HandleDefinition() {
fprintf(stderr, "Read function definition:");
FnIR->print(errs());
fprintf(stderr, "\n");
TheJIT->addModule(std::move(TheModule));
ExitOnErr(TheJIT->addModule(
ThreadSafeModule(std::move(TheModule), std::move(TheContext))));
InitializeModuleAndPassManager();
}
} else {
Expand All @@ -1164,22 +1170,24 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
if (FnAST->codegen()) {
// JIT the module containing the anonymous expression, keeping a handle so
// we can free it later.
auto H = TheJIT->addModule(std::move(TheModule));
// Create a ResourceTracker to track JIT'd memory allocated to our
// anonymous expression -- that way we can free it after executing.
auto RT = TheJIT->getMainJITDylib().createResourceTracker();

auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext));
ExitOnErr(TheJIT->addModule(std::move(TSM), RT));
InitializeModuleAndPassManager();

// Search the JIT for the __anon_expr symbol.
auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");
auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr"));

// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress();
fprintf(stderr, "Evaluated to %f\n", FP());

// Delete the anonymous expression module from the JIT.
TheJIT->removeModule(H);
ExitOnErr(RT->remove());
}
} else {
// Skip token for error recovery.
Expand Down Expand Up @@ -1253,7 +1261,7 @@ int main() {
fprintf(stderr, "ready> ");
getNextToken();

TheJIT = std::make_unique<KaleidoscopeJIT>();
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());

InitializeModuleAndPassManager();

Expand Down
113 changes: 59 additions & 54 deletions llvm/examples/Kaleidoscope/Chapter8/toy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,11 +702,12 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//

static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;
static std::map<std::string, AllocaInst *> NamedValues;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
static ExitOnError ExitOnErr;

Value *LogErrorV(const char *Str) {
LogError(Str);
Expand Down Expand Up @@ -734,11 +735,11 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
StringRef VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, VarName);
}

Value *NumberExprAST::codegen() {
return ConstantFP::get(TheContext, APFloat(Val));
return ConstantFP::get(*TheContext, APFloat(Val));
}

Value *VariableExprAST::codegen() {
Expand All @@ -748,7 +749,7 @@ Value *VariableExprAST::codegen() {
return LogErrorV("Unknown variable name");

// Load the value.
return Builder.CreateLoad(V, Name.c_str());
return Builder->CreateLoad(V, Name.c_str());
}

Value *UnaryExprAST::codegen() {
Expand All @@ -760,7 +761,7 @@ Value *UnaryExprAST::codegen() {
if (!F)
return LogErrorV("Unknown unary operator");

return Builder.CreateCall(F, OperandV, "unop");
return Builder->CreateCall(F, OperandV, "unop");
}

Value *BinaryExprAST::codegen() {
Expand All @@ -783,7 +784,7 @@ Value *BinaryExprAST::codegen() {
if (!Variable)
return LogErrorV("Unknown variable name");

Builder.CreateStore(Val, Variable);
Builder->CreateStore(Val, Variable);
return Val;
}

Expand All @@ -794,15 +795,15 @@ Value *BinaryExprAST::codegen() {

switch (Op) {
case '+':
return Builder.CreateFAdd(L, R, "addtmp");
return Builder->CreateFAdd(L, R, "addtmp");
case '-':
return Builder.CreateFSub(L, R, "subtmp");
return Builder->CreateFSub(L, R, "subtmp");
case '*':
return Builder.CreateFMul(L, R, "multmp");
return Builder->CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
L = Builder->CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
default:
break;
}
Expand All @@ -813,7 +814,7 @@ Value *BinaryExprAST::codegen() {
assert(F && "binary operator not found!");

Value *Ops[] = {L, R};
return Builder.CreateCall(F, Ops, "binop");
return Builder->CreateCall(F, Ops, "binop");
}

Value *CallExprAST::codegen() {
Expand All @@ -833,7 +834,7 @@ Value *CallExprAST::codegen() {
return nullptr;
}

return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
}

Value *IfExprAST::codegen() {
Expand All @@ -842,46 +843,46 @@ Value *IfExprAST::codegen() {
return nullptr;

// Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
CondV = Builder->CreateFCmpONE(
CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond");

Function *TheFunction = Builder.GetInsertBlock()->getParent();
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 = BasicBlock::Create(TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont");

Builder.CreateCondBr(CondV, ThenBB, ElseBB);
Builder->CreateCondBr(CondV, ThenBB, ElseBB);

// Emit then value.
Builder.SetInsertPoint(ThenBB);
Builder->SetInsertPoint(ThenBB);

Value *ThenV = Then->codegen();
if (!ThenV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
ThenBB = Builder.GetInsertBlock();
ThenBB = Builder->GetInsertBlock();

// Emit else block.
TheFunction->getBasicBlockList().push_back(ElseBB);
Builder.SetInsertPoint(ElseBB);
Builder->SetInsertPoint(ElseBB);

Value *ElseV = Else->codegen();
if (!ElseV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
ElseBB = Builder.GetInsertBlock();
ElseBB = Builder->GetInsertBlock();

// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
Builder->SetInsertPoint(MergeBB);
PHINode *PN = Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp");

PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
Expand All @@ -908,7 +909,7 @@ Value *IfExprAST::codegen() {
// br endcond, loop, endloop
// outloop:
Value *ForExprAST::codegen() {
Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Expand All @@ -919,17 +920,17 @@ Value *ForExprAST::codegen() {
return nullptr;

// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
Builder->CreateStore(StartVal, Alloca);

// Make the new basic block for the loop header, inserting after current
// block.
BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "loop", TheFunction);

// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
Builder->CreateBr(LoopBB);

// Start insertion in LoopBB.
Builder.SetInsertPoint(LoopBB);
Builder->SetInsertPoint(LoopBB);

// Within the loop, the variable is defined equal to the PHI node. If it
// shadows an existing variable, we have to restore it, so save it now.
Expand All @@ -950,7 +951,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(TheContext, APFloat(1.0));
StepVal = ConstantFP::get(*TheContext, APFloat(1.0));
}

// Compute the end condition.
Expand All @@ -960,23 +961,23 @@ Value *ForExprAST::codegen() {

// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
Value *CurVar = Builder->CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar");
Builder->CreateStore(NextVar, Alloca);

// Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
EndCond = Builder->CreateFCmpONE(
EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond");

// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
BasicBlock::Create(TheContext, "afterloop", TheFunction);
BasicBlock::Create(*TheContext, "afterloop", TheFunction);

// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
Builder->CreateCondBr(EndCond, LoopBB, AfterBB);

// Any new code will be inserted in AfterBB.
Builder.SetInsertPoint(AfterBB);
Builder->SetInsertPoint(AfterBB);

// Restore the unshadowed variable.
if (OldVal)
Expand All @@ -985,13 +986,13 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);

// for expr always returns 0.0.
return Constant::getNullValue(Type::getDoubleTy(TheContext));
return Constant::getNullValue(Type::getDoubleTy(*TheContext));
}

Value *VarExprAST::codegen() {
std::vector<AllocaInst *> OldBindings;

Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
Expand All @@ -1009,11 +1010,11 @@ Value *VarExprAST::codegen() {
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(TheContext, APFloat(0.0));
InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
}

AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Builder.CreateStore(InitVal, Alloca);
Builder->CreateStore(InitVal, Alloca);

// Remember the old variable binding so that we can restore the binding when
// we unrecurse.
Expand All @@ -1038,9 +1039,9 @@ Value *VarExprAST::codegen() {

Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(*TheContext));
FunctionType *FT =
FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);

Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
Expand All @@ -1067,8 +1068,8 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();

// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
Builder->SetInsertPoint(BB);

// Record the function arguments in the NamedValues map.
NamedValues.clear();
Expand All @@ -1077,15 +1078,15 @@ Function *FunctionAST::codegen() {
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());

// Store the initial value into the alloca.
Builder.CreateStore(&Arg, Alloca);
Builder->CreateStore(&Arg, Alloca);

// Add arguments to variable symbol table.
NamedValues[std::string(Arg.getName())] = Alloca;
}

if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
Builder->CreateRet(RetVal);

// Validate the generated code, checking for consistency.
verifyFunction(*TheFunction);
Expand All @@ -1107,7 +1108,11 @@ Function *FunctionAST::codegen() {

static void InitializeModuleAndPassManager() {
// Open a new module.
TheModule = std::make_unique<Module>("my cool jit", TheContext);
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("my cool jit", *TheContext);

// Create a new builder for the module.
Builder = std::make_unique<IRBuilder<>>(*TheContext);
}

static void HandleDefinition() {
Expand Down
138 changes: 74 additions & 64 deletions llvm/examples/Kaleidoscope/Chapter9/toy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ namespace {
class PrototypeAST;
class ExprAST;
}
static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);

struct DebugInfo {
DICompileUnit *TheCU;
DIType *DblTy;
Expand Down Expand Up @@ -814,6 +813,19 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
return ParsePrototype();
}

//===----------------------------------------------------------------------===//
// Code Generation Globals
//===----------------------------------------------------------------------===//

static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;
static ExitOnError ExitOnErr;

static std::map<std::string, AllocaInst *> NamedValues;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;

//===----------------------------------------------------------------------===//
// Debug Info Support
//===----------------------------------------------------------------------===//
Expand All @@ -830,13 +842,13 @@ DIType *DebugInfo::getDoubleTy() {

void DebugInfo::emitLocation(ExprAST *AST) {
if (!AST)
return Builder.SetCurrentDebugLocation(DebugLoc());
return Builder->SetCurrentDebugLocation(DebugLoc());
DIScope *Scope;
if (LexicalBlocks.empty())
Scope = TheCU;
else
Scope = LexicalBlocks.back();
Builder.SetCurrentDebugLocation(
Builder->SetCurrentDebugLocation(
DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
}

Expand All @@ -857,11 +869,6 @@ static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) {
// Code Generation
//===----------------------------------------------------------------------===//

static std::unique_ptr<Module> TheModule;
static std::map<std::string, AllocaInst *> NamedValues;
static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;

Value *LogErrorV(const char *Str) {
LogError(Str);
return nullptr;
Expand All @@ -888,12 +895,12 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
StringRef VarName) {
IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
TheFunction->getEntryBlock().begin());
return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), nullptr, VarName);
return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, VarName);
}

Value *NumberExprAST::codegen() {
KSDbgInfo.emitLocation(this);
return ConstantFP::get(TheContext, APFloat(Val));
return ConstantFP::get(*TheContext, APFloat(Val));
}

Value *VariableExprAST::codegen() {
Expand All @@ -904,7 +911,7 @@ Value *VariableExprAST::codegen() {

KSDbgInfo.emitLocation(this);
// Load the value.
return Builder.CreateLoad(V, Name.c_str());
return Builder->CreateLoad(V, Name.c_str());
}

Value *UnaryExprAST::codegen() {
Expand All @@ -917,7 +924,7 @@ Value *UnaryExprAST::codegen() {
return LogErrorV("Unknown unary operator");

KSDbgInfo.emitLocation(this);
return Builder.CreateCall(F, OperandV, "unop");
return Builder->CreateCall(F, OperandV, "unop");
}

Value *BinaryExprAST::codegen() {
Expand All @@ -942,7 +949,7 @@ Value *BinaryExprAST::codegen() {
if (!Variable)
return LogErrorV("Unknown variable name");

Builder.CreateStore(Val, Variable);
Builder->CreateStore(Val, Variable);
return Val;
}

Expand All @@ -953,15 +960,15 @@ Value *BinaryExprAST::codegen() {

switch (Op) {
case '+':
return Builder.CreateFAdd(L, R, "addtmp");
return Builder->CreateFAdd(L, R, "addtmp");
case '-':
return Builder.CreateFSub(L, R, "subtmp");
return Builder->CreateFSub(L, R, "subtmp");
case '*':
return Builder.CreateFMul(L, R, "multmp");
return Builder->CreateFMul(L, R, "multmp");
case '<':
L = Builder.CreateFCmpULT(L, R, "cmptmp");
L = Builder->CreateFCmpULT(L, R, "cmptmp");
// Convert bool 0/1 to double 0.0 or 1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
default:
break;
}
Expand All @@ -972,7 +979,7 @@ Value *BinaryExprAST::codegen() {
assert(F && "binary operator not found!");

Value *Ops[] = {L, R};
return Builder.CreateCall(F, Ops, "binop");
return Builder->CreateCall(F, Ops, "binop");
}

Value *CallExprAST::codegen() {
Expand All @@ -994,7 +1001,7 @@ Value *CallExprAST::codegen() {
return nullptr;
}

return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
}

Value *IfExprAST::codegen() {
Expand All @@ -1005,46 +1012,46 @@ Value *IfExprAST::codegen() {
return nullptr;

// Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
CondV = Builder->CreateFCmpONE(
CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond");

Function *TheFunction = Builder.GetInsertBlock()->getParent();
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 = BasicBlock::Create(TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else");
BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont");

Builder.CreateCondBr(CondV, ThenBB, ElseBB);
Builder->CreateCondBr(CondV, ThenBB, ElseBB);

// Emit then value.
Builder.SetInsertPoint(ThenBB);
Builder->SetInsertPoint(ThenBB);

Value *ThenV = Then->codegen();
if (!ThenV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
ThenBB = Builder.GetInsertBlock();
ThenBB = Builder->GetInsertBlock();

// Emit else block.
TheFunction->getBasicBlockList().push_back(ElseBB);
Builder.SetInsertPoint(ElseBB);
Builder->SetInsertPoint(ElseBB);

Value *ElseV = Else->codegen();
if (!ElseV)
return nullptr;

Builder.CreateBr(MergeBB);
Builder->CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
ElseBB = Builder.GetInsertBlock();
ElseBB = Builder->GetInsertBlock();

// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
Builder->SetInsertPoint(MergeBB);
PHINode *PN = Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp");

PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
Expand All @@ -1071,7 +1078,7 @@ Value *IfExprAST::codegen() {
// br endcond, loop, endloop
// outloop:
Value *ForExprAST::codegen() {
Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Expand All @@ -1084,17 +1091,17 @@ Value *ForExprAST::codegen() {
return nullptr;

// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
Builder->CreateStore(StartVal, Alloca);

// Make the new basic block for the loop header, inserting after current
// block.
BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "loop", TheFunction);

// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
Builder->CreateBr(LoopBB);

// Start insertion in LoopBB.
Builder.SetInsertPoint(LoopBB);
Builder->SetInsertPoint(LoopBB);

// Within the loop, the variable is defined equal to the PHI node. If it
// shadows an existing variable, we have to restore it, so save it now.
Expand All @@ -1115,7 +1122,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(TheContext, APFloat(1.0));
StepVal = ConstantFP::get(*TheContext, APFloat(1.0));
}

// Compute the end condition.
Expand All @@ -1125,23 +1132,23 @@ Value *ForExprAST::codegen() {

// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
Value *CurVar = Builder->CreateLoad(Alloca, VarName.c_str());
Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar");
Builder->CreateStore(NextVar, Alloca);

// Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
EndCond = Builder->CreateFCmpONE(
EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond");

// Create the "after loop" block and insert it.
BasicBlock *AfterBB =
BasicBlock::Create(TheContext, "afterloop", TheFunction);
BasicBlock::Create(*TheContext, "afterloop", TheFunction);

// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
Builder->CreateCondBr(EndCond, LoopBB, AfterBB);

// Any new code will be inserted in AfterBB.
Builder.SetInsertPoint(AfterBB);
Builder->SetInsertPoint(AfterBB);

// Restore the unshadowed variable.
if (OldVal)
Expand All @@ -1150,13 +1157,13 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);

// for expr always returns 0.0.
return Constant::getNullValue(Type::getDoubleTy(TheContext));
return Constant::getNullValue(Type::getDoubleTy(*TheContext));
}

Value *VarExprAST::codegen() {
std::vector<AllocaInst *> OldBindings;

Function *TheFunction = Builder.GetInsertBlock()->getParent();
Function *TheFunction = Builder->GetInsertBlock()->getParent();

// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
Expand All @@ -1174,11 +1181,11 @@ Value *VarExprAST::codegen() {
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(TheContext, APFloat(0.0));
InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
}

AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
Builder.CreateStore(InitVal, Alloca);
Builder->CreateStore(InitVal, Alloca);

// Remember the old variable binding so that we can restore the binding when
// we unrecurse.
Expand All @@ -1205,9 +1212,9 @@ Value *VarExprAST::codegen() {

Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(*TheContext));
FunctionType *FT =
FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);

Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
Expand All @@ -1234,8 +1241,8 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();

// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
Builder->SetInsertPoint(BB);

// Create a subprogram DIE for this function.
DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(),
Expand Down Expand Up @@ -1271,10 +1278,10 @@ Function *FunctionAST::codegen() {

DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
DebugLoc::get(LineNo, 0, SP),
Builder.GetInsertBlock());
Builder->GetInsertBlock());

// Store the initial value into the alloca.
Builder.CreateStore(&Arg, Alloca);
Builder->CreateStore(&Arg, Alloca);

// Add arguments to variable symbol table.
NamedValues[std::string(Arg.getName())] = Alloca;
Expand All @@ -1284,7 +1291,7 @@ Function *FunctionAST::codegen() {

if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
Builder->CreateRet(RetVal);

// Pop off the lexical block for the function.
KSDbgInfo.LexicalBlocks.pop_back();
Expand Down Expand Up @@ -1314,8 +1321,11 @@ Function *FunctionAST::codegen() {

static void InitializeModule() {
// Open a new module.
TheModule = std::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
TheModule->setDataLayout(TheJIT->getDataLayout());

Builder = std::make_unique<IRBuilder<>>(*TheContext);
}

static void HandleDefinition() {
Expand Down Expand Up @@ -1416,7 +1426,7 @@ int main() {
// Prime the first token.
getNextToken();

TheJIT = std::make_unique<KaleidoscopeJIT>();
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());

InitializeModule();

Expand Down
155 changes: 58 additions & 97 deletions llvm/examples/Kaleidoscope/include/KaleidoscopeJIT.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,126 +13,87 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <map>
#include "llvm/IR/LLVMContext.h"
#include <memory>
#include <string>
#include <vector>

namespace llvm {
namespace orc {

class KaleidoscopeJIT {
public:
using ObjLayerT = LegacyRTDyldObjectLinkingLayer;
using CompileLayerT = LegacyIRCompileLayer<ObjLayerT, SimpleCompiler>;

KaleidoscopeJIT()
: Resolver(createLegacyLookupResolver(
ES,
[this](StringRef Name) {
return findMangledSymbol(std::string(Name));
},
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer(AcknowledgeORCv1Deprecation, ES,
[this](VModuleKey) {
return ObjLayerT::Resources{
std::make_shared<SectionMemoryManager>(), Resolver};
}),
CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer,
SimpleCompiler(*TM)) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
}
private:
std::unique_ptr<TargetProcessControl> TPC;
std::unique_ptr<ExecutionSession> ES;

TargetMachine &getTargetMachine() { return *TM; }
DataLayout DL;
MangleAndInterner Mangle;

VModuleKey addModule(std::unique_ptr<Module> M) {
auto K = ES.allocateVModule();
cantFail(CompileLayer.addModule(K, std::move(M)));
ModuleKeys.push_back(K);
return K;
}
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer CompileLayer;

void removeModule(VModuleKey K) {
ModuleKeys.erase(find(ModuleKeys, K));
cantFail(CompileLayer.removeModule(K));
JITDylib &MainJD;

public:
KaleidoscopeJIT(std::unique_ptr<TargetProcessControl> TPC,
std::unique_ptr<ExecutionSession> ES,
JITTargetMachineBuilder JTMB, DataLayout DL)
: TPC(std::move(TPC)), ES(std::move(ES)), DL(std::move(DL)),
Mangle(*this->ES, this->DL),
ObjectLayer(*this->ES,
[]() { return std::make_unique<SectionMemoryManager>(); }),
CompileLayer(*this->ES, ObjectLayer,
std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),
MainJD(this->ES->createBareJITDylib("<main>")) {
MainJD.addGenerator(
cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
DL.getGlobalPrefix())));
}

JITSymbol findSymbol(const std::string Name) {
return findMangledSymbol(mangle(Name));
~KaleidoscopeJIT() {
if (auto Err = ES->endSession())
ES->reportError(std::move(Err));
}

private:
std::string mangle(const std::string &Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
}
return MangledName;
static Expected<std::unique_ptr<KaleidoscopeJIT>> Create() {
auto TPC = SelfTargetProcessControl::Create();
if (!TPC)
return TPC.takeError();

auto ES = std::make_unique<ExecutionSession>();

JITTargetMachineBuilder JTMB((*TPC)->getTargetTriple());

auto DL = JTMB.getDefaultDataLayoutForTarget();
if (!DL)
return DL.takeError();

return std::make_unique<KaleidoscopeJIT>(std::move(*TPC), std::move(ES),
std::move(JTMB), std::move(*DL));
}

JITSymbol findMangledSymbol(const std::string &Name) {
#ifdef _WIN32
// The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported
// flag to decide whether a symbol will be visible or not, when we call
// IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true.
//
// But for Windows COFF objects, this flag is currently never set.
// For a potential solution see: https://reviews.llvm.org/rL258665
// For now, we allow non-exported symbols on Windows as a workaround.
const bool ExportedSymbolsOnly = false;
#else
const bool ExportedSymbolsOnly = true;
#endif

// Search modules in reverse order: from last added to first added.
// This is the opposite of the usual search order for dlsym, but makes more
// sense in a REPL where we want to bind to the newest available definition.
for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))
if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
return Sym;

// If we can't find the symbol in the JIT, try looking in the host process.
if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);

#ifdef _WIN32
// For Windows retry without "_" at beginning, as RTDyldMemoryManager uses
// GetProcAddress and standard libraries like msvcrt.dll use names
// with and without "_" (for example "_itoa" but "sin").
if (Name.length() > 2 && Name[0] == '_')
if (auto SymAddr =
RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1)))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
#endif

return nullptr;
const DataLayout &getDataLayout() const { return DL; }

JITDylib &getMainJITDylib() { return MainJD; }

Error addModule(ThreadSafeModule TSM, ResourceTrackerSP RT = nullptr) {
if (!RT)
RT = MainJD.getDefaultResourceTracker();
return CompileLayer.add(RT, std::move(TSM));
}

ExecutionSession ES;
std::shared_ptr<SymbolResolver> Resolver;
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
std::vector<VModuleKey> ModuleKeys;
Expected<JITEvaluatedSymbol> lookup(StringRef Name) {
return ES->lookup({&MainJD}, Mangle(Name.str()));
}
};

} // end namespace orc
Expand Down
13 changes: 13 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ class TPCIndirectionUtils {
std::vector<std::unique_ptr<Allocation>> IndirectStubAllocs;
};

/// This will call writeResolver on the given TPCIndirectionUtils instance
/// to set up re-entry via a function that will directly return the trampoline
/// landing address.
///
/// The TPCIndirectionUtils' LazyCallThroughManager must have been previously
/// created via TPCIndirectionUtils::createLazyCallThroughManager.
///
/// The TPCIndirectionUtils' writeResolver method must not have been previously
/// called.
///
/// This function is experimental and likely subject to revision.
Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU);

namespace detail {

template <typename ORCABI>
Expand Down
21 changes: 21 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/TPCIndirectionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
#include "llvm/Support/MathExtras.h"

#include <future>

using namespace llvm;
using namespace llvm::orc;

Expand Down Expand Up @@ -398,5 +400,24 @@ TPCIndirectionUtils::getIndirectStubs(unsigned NumStubs) {
return std::move(Result);
}

static JITTargetAddress reentry(JITTargetAddress LCTMAddr,
JITTargetAddress TrampolineAddr) {
auto &LCTM = *jitTargetAddressToPointer<LazyCallThroughManager *>(LCTMAddr);
std::promise<JITTargetAddress> LandingAddrP;
auto LandingAddrF = LandingAddrP.get_future();
LCTM.resolveTrampolineLandingAddress(
TrampolineAddr,
[&](JITTargetAddress Addr) { LandingAddrP.set_value(Addr); });
return LandingAddrF.get();
}

Error setUpInProcessLCTMReentryViaTPCIU(TPCIndirectionUtils &TPCIU) {
auto &LCTM = TPCIU.getLazyCallThroughManager();
return TPCIU
.writeResolverBlock(pointerToJITTargetAddress(&reentry),
pointerToJITTargetAddress(&LCTM))
.takeError();
}

} // end namespace orc
} // end namespace llvm