llvm.org GIT mirror llvm / e639d4f
[Kaleidoscope] Fix a bug in Chapter 4 of the Kaleidoscope tutorial where repeat calls to functions weren't evaluated correctly. Patch by Charlie Turner. Thanks Charlie! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226308 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 5 years ago
1 changed file(s) with 253 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
380380 }
381381
382382 //===----------------------------------------------------------------------===//
383 // Quick and dirty hack
384 //===----------------------------------------------------------------------===//
385
386 // FIXME: Obviously we can do better than this
387 std::string GenerateUniqueName(const char *root)
388 {
389 static int i = 0;
390 char s[16];
391 sprintf(s, "%s%d", root, i++);
392 std::string S = s;
393 return S;
394 }
395
396 std::string MakeLegalFunctionName(std::string Name)
397 {
398 std::string NewName;
399 if (!Name.length())
400 return GenerateUniqueName("anon_func_");
401
402 // Start with what we have
403 NewName = Name;
404
405 // Look for a numberic first character
406 if (NewName.find_first_of("0123456789") == 0) {
407 NewName.insert(0, 1, 'n');
408 }
409
410 // Replace illegal characters with their ASCII equivalent
411 std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
412 size_t pos;
413 while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {
414 char old_c = NewName.at(pos);
415 char new_str[16];
416 sprintf(new_str, "%d", (int)old_c);
417 NewName = NewName.replace(pos, 1, new_str);
418 }
419
420 return NewName;
421 }
422
423 //===----------------------------------------------------------------------===//
424 // MCJIT helper class
425 //===----------------------------------------------------------------------===//
426
427 class MCJITHelper
428 {
429 public:
430 MCJITHelper(LLVMContext& C) : Context(C), OpenModule(NULL) {}
431 ~MCJITHelper();
432
433 Function *getFunction(const std::string FnName);
434 Module *getModuleForNewFunction();
435 void *getPointerToFunction(Function* F);
436 void *getSymbolAddress(const std::string &Name);
437 void dump();
438
439 private:
440 typedef std::vector ModuleVector;
441 typedef std::vector EngineVector;
442
443 LLVMContext &Context;
444 Module *OpenModule;
445 ModuleVector Modules;
446 EngineVector Engines;
447 };
448
449 class HelpingMemoryManager : public SectionMemoryManager
450 {
451 HelpingMemoryManager(const HelpingMemoryManager&) LLVM_DELETED_FUNCTION;
452 void operator=(const HelpingMemoryManager&) LLVM_DELETED_FUNCTION;
453
454 public:
455 HelpingMemoryManager(MCJITHelper *Helper) : MasterHelper(Helper) {}
456 virtual ~HelpingMemoryManager() {}
457
458 /// This method returns the address of the specified symbol.
459 /// Our implementation will attempt to find symbols in other
460 /// modules associated with the MCJITHelper to cross link symbols
461 /// from one generated module to another.
462 virtual uint64_t getSymbolAddress(const std::string &Name) override;
463 private:
464 MCJITHelper *MasterHelper;
465 };
466
467 uint64_t HelpingMemoryManager::getSymbolAddress(const std::string &Name)
468 {
469 uint64_t FnAddr = SectionMemoryManager::getSymbolAddress(Name);
470 if (FnAddr)
471 return FnAddr;
472
473 uint64_t HelperFun = (uint64_t) MasterHelper->getSymbolAddress(Name);
474 if (!HelperFun)
475 report_fatal_error("Program used extern function '" + Name +
476 "' which could not be resolved!");
477
478 return HelperFun;
479 }
480
481 MCJITHelper::~MCJITHelper()
482 {
483 if (OpenModule)
484 delete OpenModule;
485 EngineVector::iterator begin = Engines.begin();
486 EngineVector::iterator end = Engines.end();
487 EngineVector::iterator it;
488 for (it = begin; it != end; ++it)
489 delete *it;
490 }
491
492 Function *MCJITHelper::getFunction(const std::string FnName) {
493 ModuleVector::iterator begin = Modules.begin();
494 ModuleVector::iterator end = Modules.end();
495 ModuleVector::iterator it;
496 for (it = begin; it != end; ++it) {
497 Function *F = (*it)->getFunction(FnName);
498 if (F) {
499 if (*it == OpenModule)
500 return F;
501
502 assert(OpenModule != NULL);
503
504 // This function is in a module that has already been JITed.
505 // We need to generate a new prototype for external linkage.
506 Function *PF = OpenModule->getFunction(FnName);
507 if (PF && !PF->empty()) {
508 ErrorF("redefinition of function across modules");
509 return 0;
510 }
511
512 // If we don't have a prototype yet, create one.
513 if (!PF)
514 PF = Function::Create(F->getFunctionType(),
515 Function::ExternalLinkage,
516 FnName,
517 OpenModule);
518 return PF;
519 }
520 }
521 return NULL;
522 }
523
524 Module *MCJITHelper::getModuleForNewFunction() {
525 // If we have a Module that hasn't been JITed, use that.
526 if (OpenModule)
527 return OpenModule;
528
529 // Otherwise create a new Module.
530 std::string ModName = GenerateUniqueName("mcjit_module_");
531 Module *M = new Module(ModName, Context);
532 Modules.push_back(M);
533 OpenModule = M;
534 return M;
535 }
536
537 void *MCJITHelper::getPointerToFunction(Function* F) {
538 // See if an existing instance of MCJIT has this function.
539 EngineVector::iterator begin = Engines.begin();
540 EngineVector::iterator end = Engines.end();
541 EngineVector::iterator it;
542 for (it = begin; it != end; ++it) {
543 void *P = (*it)->getPointerToFunction(F);
544 if (P)
545 return P;
546 }
547
548 // If we didn't find the function, see if we can generate it.
549 if (OpenModule) {
550 std::string ErrStr;
551 ExecutionEngine *NewEngine = EngineBuilder(std::unique_ptr(OpenModule))
552 .setErrorStr(&ErrStr)
553 .setMCJITMemoryManager(std::unique_ptr(new HelpingMemoryManager(this)))
554 .create();
555 if (!NewEngine) {
556 fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
557 exit(1);
558 }
559
560 // Create a function pass manager for this engine
561 FunctionPassManager *FPM = new FunctionPassManager(OpenModule);
562
563 // Set up the optimizer pipeline. Start with registering info about how the
564 // target lays out data structures.
565 OpenModule->setDataLayout(NewEngine->getDataLayout());
566 FPM->add(new DataLayoutPass());
567 // Provide basic AliasAnalysis support for GVN.
568 FPM->add(createBasicAliasAnalysisPass());
569 // Promote allocas to registers.
570 FPM->add(createPromoteMemoryToRegisterPass());
571 // Do simple "peephole" optimizations and bit-twiddling optzns.
572 FPM->add(createInstructionCombiningPass());
573 // Reassociate expressions.
574 FPM->add(createReassociatePass());
575 // Eliminate Common SubExpressions.
576 FPM->add(createGVNPass());
577 // Simplify the control flow graph (deleting unreachable blocks, etc).
578 FPM->add(createCFGSimplificationPass());
579 FPM->doInitialization();
580
581 // For each function in the module
582 Module::iterator it;
583 Module::iterator end = OpenModule->end();
584 for (it = OpenModule->begin(); it != end; ++it) {
585 // Run the FPM on this function
586 FPM->run(*it);
587 }
588
589 // We don't need this anymore
590 delete FPM;
591
592 OpenModule = NULL;
593 Engines.push_back(NewEngine);
594 NewEngine->finalizeObject();
595 return NewEngine->getPointerToFunction(F);
596 }
597 return NULL;
598 }
599
600 void *MCJITHelper::getSymbolAddress(const std::string &Name)
601 {
602 // Look for the symbol in each of our execution engines.
603 EngineVector::iterator begin = Engines.begin();
604 EngineVector::iterator end = Engines.end();
605 EngineVector::iterator it;
606 for (it = begin; it != end; ++it) {
607 uint64_t FAddr = (*it)->getFunctionAddress(Name);
608 if (FAddr) {
609 return (void *)FAddr;
610 }
611 }
612 return NULL;
613 }
614
615 void MCJITHelper::dump()
616 {
617 ModuleVector::iterator begin = Modules.begin();
618 ModuleVector::iterator end = Modules.end();
619 ModuleVector::iterator it;
620 for (it = begin; it != end; ++it)
621 (*it)->dump();
622 }
623 //===----------------------------------------------------------------------===//
383624 // Code Generation
384625 //===----------------------------------------------------------------------===//
385626
386 static Module *TheModule;
627 static MCJITHelper *JITHelper;
387628 static IRBuilder<> Builder(getGlobalContext());
388629 static std::map NamedValues;
389 static FunctionPassManager *TheFPM;
390630
391631 Value *ErrorV(const char *Str) {
392632 Error(Str);
428668
429669 Value *CallExprAST::Codegen() {
430670 // Look up the name in the global module table.
431 Function *CalleeF = TheModule->getFunction(Callee);
671 Function *CalleeF = JITHelper->getFunction(Callee);
432672 if (CalleeF == 0)
433673 return ErrorV("Unknown function referenced");
434674
453693 FunctionType *FT =
454694 FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
455695
696 std::string FnName = MakeLegalFunctionName(Name);
697
698 Module *M = JITHelper->getModuleForNewFunction();
699
456700 Function *F =
457 Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
701 Function::Create(FT, Function::ExternalLinkage, FnName, M);
458702
459703 // If F conflicted, there was already something named 'Name'. If it has a
460704 // body, don't allow redefinition or reextern.
461 if (F->getName() != Name) {
705 if (F->getName() != FnName) {
462706 // Delete the one we just made and get the existing one.
463707 F->eraseFromParent();
464 F = TheModule->getFunction(Name);
465
708 F = JITHelper->getFunction(Name);
466709 // If F already has a body, reject this.
467710 if (!F->empty()) {
468711 ErrorF("redefinition of function");
507750 // Validate the generated code, checking for consistency.
508751 verifyFunction(*TheFunction);
509752
510 // Optimize the function.
511 TheFPM->run(*TheFunction);
512
513753 return TheFunction;
514754 }
515755
521761 //===----------------------------------------------------------------------===//
522762 // Top-Level parsing and JIT Driver
523763 //===----------------------------------------------------------------------===//
524
525 static ExecutionEngine *TheExecutionEngine;
526764
527765 static void HandleDefinition() {
528766 if (FunctionAST *F = ParseDefinition()) {
552790 // Evaluate a top-level expression into an anonymous function.
553791 if (FunctionAST *F = ParseTopLevelExpr()) {
554792 if (Function *LF = F->Codegen()) {
555 TheExecutionEngine->finalizeObject();
556793 // JIT the function, returning a function pointer.
557 void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
794 void *FPtr = JITHelper->getPointerToFunction(LF);
558795
559796 // Cast it to the right type (takes no arguments, returns a double) so we
560797 // can call it as a native function.
609846 InitializeNativeTargetAsmPrinter();
610847 InitializeNativeTargetAsmParser();
611848 LLVMContext &Context = getGlobalContext();
849 JITHelper = new MCJITHelper(Context);
612850
613851 // Install standard binary operators.
614852 // 1 is lowest precedence.
621859 fprintf(stderr, "ready> ");
622860 getNextToken();
623861
624 // Make the module, which holds all the code.
625 std::unique_ptr Owner = make_unique("my cool jit", Context);
626 TheModule = Owner.get();
627
628 // Create the JIT. This takes ownership of the module.
629 std::string ErrStr;
630 TheExecutionEngine =
631 EngineBuilder(std::move(Owner))
632 .setErrorStr(&ErrStr)
633 .setMCJITMemoryManager(llvm::make_unique())
634 .create();
635 if (!TheExecutionEngine) {
636 fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
637 exit(1);
638 }
639
640 FunctionPassManager OurFPM(TheModule);
641
642 // Set up the optimizer pipeline. Start with registering info about how the
643 // target lays out data structures.
644 TheModule->setDataLayout(TheExecutionEngine->getDataLayout());
645 OurFPM.add(new DataLayoutPass());
646 // Provide basic AliasAnalysis support for GVN.
647 OurFPM.add(createBasicAliasAnalysisPass());
648 // Do simple "peephole" optimizations and bit-twiddling optzns.
649 OurFPM.add(createInstructionCombiningPass());
650 // Reassociate expressions.
651 OurFPM.add(createReassociatePass());
652 // Eliminate Common SubExpressions.
653 OurFPM.add(createGVNPass());
654 // Simplify the control flow graph (deleting unreachable blocks, etc).
655 OurFPM.add(createCFGSimplificationPass());
656
657 OurFPM.doInitialization();
658
659 // Set the global so the code gen can use this.
660 TheFPM = &OurFPM;
661
662862 // Run the main "interpreter loop" now.
663863 MainLoop();
664864
665 TheFPM = 0;
666
667865 // Print out all of the generated code.
668 TheModule->dump();
866 JITHelper->dump();
669867
670868 return 0;
671869 }