/// initialize_module - perform setup of the LLVM code generation system. void BrainFTraceRecorder::initialize_module() { LLVMContext &Context = module->getContext(); // Initialize the code generator, and enable aggressive code generation. InitializeNativeTarget(); EngineBuilder builder(module); builder.setOptLevel(CodeGenOpt::Aggressive); EE = builder.create(); // Create a FunctionPassManager to handle running optimization passes // on our generated code. Setup a basic suite of optimizations for it. FPM = new llvm::FunctionPassManager(module); FPM->add(createInstructionCombiningPass()); FPM->add(createCFGSimplificationPass()); FPM->add(createScalarReplAggregatesPass()); FPM->add(createSimplifyLibCallsPass()); FPM->add(createInstructionCombiningPass()); FPM->add(createJumpThreadingPass()); FPM->add(createCFGSimplificationPass()); FPM->add(createInstructionCombiningPass()); FPM->add(createCFGSimplificationPass()); FPM->add(createReassociatePass()); FPM->add(createLoopRotatePass()); FPM->add(createLICMPass()); FPM->add(createLoopUnswitchPass(false)); FPM->add(createInstructionCombiningPass()); FPM->add(createIndVarSimplifyPass()); FPM->add(createLoopDeletionPass()); FPM->add(createLoopUnrollPass()); FPM->add(createInstructionCombiningPass()); FPM->add(createGVNPass()); FPM->add(createSCCPPass()); FPM->add(createInstructionCombiningPass()); FPM->add(createJumpThreadingPass()); FPM->add(createDeadStoreEliminationPass()); FPM->add(createAggressiveDCEPass()); FPM->add(createCFGSimplificationPass()); // Cache the LLVM type signature of an opcode function int_type = sizeof(size_t) == 4 ? IntegerType::getInt32Ty(Context) : IntegerType::getInt64Ty(Context); const Type *data_type = PointerType::getUnqual(IntegerType::getInt8Ty(Context)); std::vector<const Type*> args; args.push_back(int_type); args.push_back(data_type); op_type = FunctionType::get(Type::getVoidTy(Context), args, false); // Setup a global variable in the LLVM module to represent the bytecode // array. Bind it to the actual bytecode array at JIT time. const Type *bytecode_type = PointerType::getUnqual(op_type); bytecode_array = cast<GlobalValue>(module-> getOrInsertGlobal("BytecodeArray", bytecode_type)); EE->addGlobalMapping(bytecode_array, BytecodeArray); // Setup a similar mapping for the global mode flag. const IntegerType *flag_type = IntegerType::get(Context, 8); mode_flag = cast<GlobalValue>(module->getOrInsertGlobal("mode", flag_type)); EE->addGlobalMapping(mode_flag, &mode); // Setup a similar mapping for the global extension root flag. ext_root = cast<GlobalValue>(module->getOrInsertGlobal("ext_root", int_type)); EE->addGlobalMapping(ext_root, &extension_root); // Setup a similar mapping for the global extension leaf flag. ext_leaf = cast<GlobalValue>(module->getOrInsertGlobal("ext_leaf", int_type)); EE->addGlobalMapping(ext_leaf, &extension_leaf); // Cache LLVM declarations for putchar() and getchar(). const Type *int_type = sizeof(int) == 4 ? IntegerType::getInt32Ty(Context) : IntegerType::getInt64Ty(Context); putchar_func = module->getOrInsertFunction("putchar", int_type, int_type, NULL); getchar_func = module->getOrInsertFunction("getchar", int_type, NULL); }
KBIRRunner::KBIRRunner( std::string s, DOMDocument *domDoc ){ fSourceFile = s; fDom = domDoc; S_Agenda = new Agenda(); InitializeNativeTarget(); }
ModelGeneratorContext::ModelGeneratorContext(std::string const &sbml, unsigned options) : ownedDoc(0), doc(0), symbols(0), modelSymbols(0), errString(new string()), options(options), moietyConverter(0), functionPassManager(0) { if (options & rr::ModelGenerator::CONSERVED_MOIETIES) { Log(Logger::LOG_NOTICE) << "performing conserved moiety conversion"; moietyConverter = new rr::conservation::ConservedMoietyConverter(); ownedDoc = checkedReadSBMLFromString(sbml.c_str()); if (moietyConverter->setDocument(ownedDoc) != LIBSBML_OPERATION_SUCCESS) { throw_llvm_exception("error setting conserved moiety converter document"); } if (moietyConverter->convert() != LIBSBML_OPERATION_SUCCESS) { throw_llvm_exception("error converting document to conserved moieties"); } doc = moietyConverter->getDocument(); SBMLWriter sw; char* convertedStr = sw.writeToString(doc); Log(Logger::LOG_NOTICE) << "***************** Conserved Moiety Converted Document ***************"; Log(Logger::LOG_NOTICE) << convertedStr; Log(Logger::LOG_NOTICE) << "*********************************************************************"; delete convertedStr; } else { ownedDoc = checkedReadSBMLFromString(sbml.c_str()); doc = ownedDoc; } symbols = new LLVMModelDataSymbols(doc->getModel(), options); modelSymbols = new LLVMModelSymbols(getModel(), *symbols); // initialize LLVM // TODO check result InitializeNativeTarget(); context = new LLVMContext(); // Make the module, which holds all the code. module = new Module("LLVM Module", *context); builder = new IRBuilder<>(*context); // engine take ownership of module EngineBuilder engineBuilder(module); engineBuilder.setErrorStr(errString); executionEngine = engineBuilder.create(); addGlobalMappings(); createLibraryFunctions(module); ModelDataIRBuilder::createModelDataStructType(module, executionEngine, *symbols); initFunctionPassManager(); }
IRCompiler::IRCompiler() { InitializeNativeTarget(); }
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; }