void ModelGeneratorContext::initFunctionPassManager() { if (options & ModelGenerator::OPTIMIZE) { functionPassManager = new FunctionPassManager(module); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. // we only support LLVM >= 3.1 #if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR == 1) functionPassManager->add(new TargetData(*executionEngine->getTargetData())); #else functionPassManager->add(new DataLayout(*executionEngine->getDataLayout())); #endif // Provide basic AliasAnalysis support for GVN. functionPassManager->add(createBasicAliasAnalysisPass()); if (options & ModelGenerator::OPTIMIZE_INSTRUCTION_SIMPLIFIER) { Log(Logger::LOG_INFORMATION) << "using OPTIMIZE_INSTRUCTION_SIMPLIFIER"; functionPassManager->add(createInstructionSimplifierPass()); } if (options & ModelGenerator::OPTIMIZE_INSTRUCTION_COMBINING) { Log(Logger::LOG_INFORMATION) << "using OPTIMIZE_INSTRUCTION_COMBINING"; functionPassManager->add(createInstructionCombiningPass()); } if(options & ModelGenerator::OPTIMIZE_GVN) { Log(Logger::LOG_INFORMATION) << "using GVN optimization"; functionPassManager->add(createGVNPass()); } if (options & ModelGenerator::OPTIMIZE_CFG_SIMPLIFICATION) { Log(Logger::LOG_INFORMATION) << "using OPTIMIZE_CFG_SIMPLIFICATION"; functionPassManager->add(createCFGSimplificationPass()); } if (options & ModelGenerator::OPTIMIZE_DEAD_INST_ELIMINATION) { Log(Logger::LOG_INFORMATION) << "using OPTIMIZE_DEAD_INST_ELIMINATION"; functionPassManager->add(createDeadInstEliminationPass()); } if (options & ModelGenerator::OPTIMIZE_DEAD_CODE_ELIMINATION) { Log(Logger::LOG_INFORMATION) << "using OPTIMIZE_DEAD_CODE_ELIMINATION"; functionPassManager->add(createDeadCodeEliminationPass()); } functionPassManager->doInitialization(); } }
main_func_type jit_engine::compile(const ast::Program &prog) { llvm::LLVMContext &c=llvm::getGlobalContext(); llvm::Module *m=new llvm::Module("brainfuck", c); brainfuck::codegen(*m, prog); //m->dump(); std::string ErrStr; ExecutionEngine *TheExecutionEngine = EngineBuilder(m).setErrorStr(&ErrStr).create(); if (!TheExecutionEngine) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } Function *f_main=m->getFunction("main"); // Optimize, target dependant if(optimization_level_>0) { FunctionPassManager OurFPM(m); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData())); // Provide basic AliasAnalysis support for GVN. OurFPM.add(createBasicAliasAnalysisPass()); // 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.add(createLoopSimplifyPass()); //OurFPM.add(createBlockPlacementPass()); //OurFPM.add(createConstantPropagationPass()); OurFPM.doInitialization(); OurFPM.run(*f_main); } //m->dump(); void *rp=TheExecutionEngine->getPointerToFunction(f_main); main_func_type fp=reinterpret_cast<main_func_type>(rp); return fp; }
static void addOptimizationPasses(T *PM) { #ifdef JL_DEBUG_BUILD PM->add(createVerifierPass()); #endif #ifdef __has_feature # if __has_feature(address_sanitizer) # if defined(LLVM37) && !defined(LLVM38) // LLVM 3.7 BUG: ASAN pass doesn't properly initialize its dependencies initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); # endif PM->add(createAddressSanitizerFunctionPass()); # endif # if __has_feature(memory_sanitizer) PM->add(llvm::createMemorySanitizerPass(true)); # endif #endif if (jl_options.opt_level <= 1) { return; } #ifdef LLVM37 PM->add(createTargetTransformInfoWrapperPass(jl_TargetMachine->getTargetIRAnalysis())); #else jl_TargetMachine->addAnalysisPasses(*PM); #endif #ifdef LLVM38 PM->add(createTypeBasedAAWrapperPass()); #else PM->add(createTypeBasedAliasAnalysisPass()); #endif if (jl_options.opt_level >= 3) { #ifdef LLVM38 PM->add(createBasicAAWrapperPass()); #else PM->add(createBasicAliasAnalysisPass()); #endif } // list of passes from vmkit PM->add(createCFGSimplificationPass()); // Clean up disgusting code PM->add(createPromoteMemoryToRegisterPass());// Kill useless allocas #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. #endif PM->add(createSROAPass()); // Break up aggregate allocas #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. #endif PM->add(createJumpThreadingPass()); // Thread jumps. // NOTE: CFG simp passes after this point seem to hurt native codegen. // See issue #6112. Should be re-evaluated when we switch to MCJIT. //PM->add(createCFGSimplificationPass()); // Merge & remove BBs #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); // Combine silly seq's #endif //PM->add(createCFGSimplificationPass()); // Merge & remove BBs PM->add(createReassociatePass()); // Reassociate expressions // this has the potential to make some things a bit slower //PM->add(createBBVectorizePass()); PM->add(createEarlyCSEPass()); //// **** PM->add(createLoopIdiomPass()); //// **** PM->add(createLoopRotatePass()); // Rotate loops. // LoopRotate strips metadata from terminator, so run LowerSIMD afterwards PM->add(createLowerSimdLoopPass()); // Annotate loop marked with "simdloop" as LLVM parallel loop PM->add(createLICMPass()); // Hoist loop invariants PM->add(createLoopUnswitchPass()); // Unswitch loops. // Subsequent passes not stripping metadata from terminator #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); #endif PM->add(createIndVarSimplifyPass()); // Canonicalize indvars PM->add(createLoopDeletionPass()); // Delete dead loops #if defined(LLVM35) PM->add(createSimpleLoopUnrollPass()); // Unroll small loops #else PM->add(createLoopUnrollPass()); // Unroll small loops #endif #if !defined(LLVM35) && !defined(INSTCOMBINE_BUG) PM->add(createLoopVectorizePass()); // Vectorize loops #endif //PM->add(createLoopStrengthReducePass()); // (jwb added) #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); // Clean up after the unroller #endif PM->add(createGVNPass()); // Remove redundancies //PM->add(createMemCpyOptPass()); // Remove memcpy / form memset PM->add(createSCCPPass()); // Constant prop with SCCP // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. PM->add(createSinkingPass()); ////////////// **** PM->add(createInstructionSimplifierPass());///////// **** #ifndef INSTCOMBINE_BUG PM->add(createInstructionCombiningPass()); #endif PM->add(createJumpThreadingPass()); // Thread jumps PM->add(createDeadStoreEliminationPass()); // Delete dead stores #if !defined(INSTCOMBINE_BUG) if (jl_options.opt_level >= 3) { #ifdef LLVM39 initializeDemandedBitsPass(*PassRegistry::getPassRegistry()); #endif PM->add(createSLPVectorizerPass()); // Vectorize straight-line code } #endif PM->add(createAggressiveDCEPass()); // Delete dead instructions #if !defined(INSTCOMBINE_BUG) if (jl_options.opt_level >= 3) PM->add(createInstructionCombiningPass()); // Clean up after SLP loop vectorizer #endif #if defined(LLVM35) PM->add(createLoopVectorizePass()); // Vectorize loops PM->add(createInstructionCombiningPass()); // Clean up after loop vectorizer #endif //PM->add(createCFGSimplificationPass()); // Merge & remove BBs }
/// adopted from: llvm-2.9/include/llvm/Support/StandardPasses.h void optimizeFunction(Function* f, const bool disableLICM, const bool disableLoopRotate) { assert (f); assert (f->getParent()); Module* mod = f->getParent(); TargetData* targetData = new TargetData(mod); const unsigned OptimizationLevel = 3; const bool OptimizeSize = false; const bool UnitAtATime = true; const bool UnrollLoops = true; const bool SimplifyLibCalls = true; const bool HaveExceptions = false; Pass* InliningPass = createFunctionInliningPass(275); //PassManager Passes; FunctionPassManager Passes(mod); Passes.add(targetData); // // custom // Passes.add(createScalarReplAggregatesPass(-1, false)); // // createStandardFunctionPasses // Passes.add(createCFGSimplificationPass()); Passes.add(createPromoteMemoryToRegisterPass()); Passes.add(createInstructionCombiningPass()); // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that // BasicAliasAnalysis wins if they disagree. This is intended to help // support "obvious" type-punning idioms. Passes.add(createTypeBasedAliasAnalysisPass()); Passes.add(createBasicAliasAnalysisPass()); // Start of function pass. // Break up aggregate allocas, using SSAUpdater. Passes.add(createScalarReplAggregatesPass(-1, false)); Passes.add(createEarlyCSEPass()); // Catch trivial redundancies if (SimplifyLibCalls) Passes.add(createSimplifyLibCallsPass()); // Library Call Optimizations Passes.add(createJumpThreadingPass()); // Thread jumps. Passes.add(createCorrelatedValuePropagationPass()); // Propagate conditionals Passes.add(createCFGSimplificationPass()); // Merge & remove BBs Passes.add(createInstructionCombiningPass()); // Combine silly seq's Passes.add(createTailCallEliminationPass()); // Eliminate tail calls Passes.add(createCFGSimplificationPass()); // Merge & remove BBs Passes.add(createReassociatePass()); // Reassociate expressions if (!disableLoopRotate) Passes.add(createLoopRotatePass()); // Rotate Loop // makes packetized Mandelbrot fail if (!disableLICM) Passes.add(createLICMPass()); // Hoist loop invariants // makes scalar driver crash after optimization //Passes.add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel < 3)); // breaks DCT with UNIFORM_ANALYSIS=0 Passes.add(createInstructionCombiningPass()); Passes.add(createIndVarSimplifyPass()); // Canonicalize indvars Passes.add(createLoopIdiomPass()); // Recognize idioms like memset. Passes.add(createLoopDeletionPass()); // Delete dead loops if (UnrollLoops) Passes.add(createLoopUnrollPass()); // Unroll small loops Passes.add(createInstructionCombiningPass()); // Clean up after the unroller if (OptimizationLevel > 1) Passes.add(createGVNPass()); // Remove redundancies Passes.add(createMemCpyOptPass()); // Remove memcpy / form memset Passes.add(createSCCPPass()); // Constant prop with SCCP // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. Passes.add(createInstructionCombiningPass()); Passes.add(createJumpThreadingPass()); // Thread jumps Passes.add(createCorrelatedValuePropagationPass()); Passes.add(createDeadStoreEliminationPass()); // Delete dead stores Passes.add(createAggressiveDCEPass()); // Delete dead instructions Passes.add(createCFGSimplificationPass()); // Merge & remove BBs WFVOPENCL_DEBUG( Passes.add(createVerifierPass()); );
bool CompiledCondition::compile(){ InitializeNativeTarget(); // Assume we're on main thread... LLVMContext &context = getGlobalContext(); // Initialize module Module* module = new Module("Compiled function", context); // Create exection engine ExecutionEngine* engine = EngineBuilder(module).create(); /********** Generate code **********/ //Get a type for representing an integer pointer //Maybe this should be unsigned integer pointer type... PointerType* integerPointerType = PointerType::get(IntegerType::get(module->getContext(), 32), 0); //Create function type, for our function, int*, int* -> bool vector<const Type*> paramType; paramType.push_back(integerPointerType); paramType.push_back(integerPointerType); FunctionType* functionType = FunctionType::get(IntegerType::get(module->getContext(), 8), paramType, false); //Declare new function Function* function = Function::Create(functionType, GlobalValue::ExternalLinkage, "evaluate", module); //Use C calling convention function->setCallingConv(CallingConv::C); //TODO: Read documentation and reconsider this //Get arguments from function Function::arg_iterator args = function->arg_begin(); Value* marking = args++; Value* valuation = args++; marking->setName("marking"); valuation->setName("valuation"); //Create function block BasicBlock* functionBlock = BasicBlock::Create(module->getContext(), "functionBlock", function, 0); //Generate code CodeGenerationContext codeGenContext(marking, valuation, functionBlock, context); Value* result = _cond->codegen(codeGenContext); //Zero extend the result, e.g. make it a 8 bit bool CastInst* retval = new ZExtInst(result, IntegerType::get(module->getContext(), 8), "retval", functionBlock); //Create a return instruction ReturnInst::Create(module->getContext(), retval, functionBlock); /********** Optimize and Compile **********/ // Create function pass manager, to optimize query FunctionPassManager optimizer(module); optimizer.add(new TargetData(*engine->getTargetData())); optimizer.add(createBasicAliasAnalysisPass()); optimizer.add(createInstructionCombiningPass()); optimizer.add(createReassociatePass()); optimizer.add(createGVNPass()); optimizer.add(createCFGSimplificationPass()); optimizer.doInitialization(); // Verify function, errors written to stderr if(verifyFunction(*function)) return false; // Optimize function optimizer.run(*function); // Compile the function _nativeFunction = (bool(*)(const MarkVal*, const VarVal*))engine->getPointerToFunction(function); return _nativeFunction != NULL; }