void Matcher::processBasicBlock(Function *F) { for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) { /** Use first and last instruction to get the scope information **/ Instruction *first = & FI->front(); Instruction *last = & FI->back(); if (first == NULL || last == NULL) { errs() << "NULL scope instructions " << "\n"; continue; } DebugLoc Loc = first->getDebugLoc(); if (Loc.isUnknown()) { errs() << "Unknown LOC information" << "\n"; continue; } errs() << "Block :" << Loc.getLine(); Loc = last->getDebugLoc(); if (Loc.isUnknown()) { errs() << "Unknown LOC information" << "\n"; continue; } errs() << ", " << Loc.getLine() << "\n"; } }
void* Compiler::generate_function(bool indy) { if(!mci_) { if(!function_) return NULL; if(indy) ctx_->llvm_state()->shared().gc_independent(ctx_->llvm_state()); if(ctx_->llvm_state()->jit_dump_code() & cSimple) { llvm::outs() << "[[[ LLVM Simple IR ]]]\n"; llvm::outs() << *function_ << "\n"; } std::vector<BasicBlock*> to_remove; bool Broken = false; for(Function::iterator I = function_->begin(), E = function_->end(); I != E; ++I) { if(I->empty()) { BasicBlock& bb = *I; // No one jumps to it.... if(llvm::pred_begin(&bb) == llvm::pred_end(&bb)) { to_remove.push_back(&bb); } else { llvm::outs() << "Basic Block is empty and used!\n"; } } else if(!I->back().isTerminator()) { llvm::errs() << "Basic Block does not have terminator!\n"; llvm::errs() << *I << "\n"; llvm::errs() << "\n"; Broken = true; } } for(std::vector<BasicBlock*>::iterator i = to_remove.begin(); i != to_remove.end(); ++i) { (*i)->eraseFromParent(); } if(Broken or llvm::verifyFunction(*function_, PrintMessageAction)) { llvm::outs() << "ERROR: complication error detected.\n"; llvm::outs() << "ERROR: Please report the above message and the\n"; llvm::outs() << " code below to http://github.com/rubinius/rubinius/issues\n"; llvm::outs() << *function_ << "\n"; function_ = NULL; if(indy) ctx_->llvm_state()->shared().gc_dependent(ctx_->llvm_state()); return NULL; } ctx_->passes()->run(*function_); if(ctx_->llvm_state()->jit_dump_code() & cOptimized) { llvm::outs() << "[[[ LLVM Optimized IR: ]]]\n"; llvm::outs() << *function_ << "\n"; } mci_ = new llvm::MachineCodeInfo(); ctx_->engine()->runJITOnFunction(function_, mci_); ctx_->llvm_state()->add_code_bytes(mci_->size()); // If we're not in JIT debug mode, delete the body IR, now that we're // done with it. // This saves us 100M+ of memory in a full spec run. if(!ctx_->llvm_state()->debug_p()) { function_->dropAllReferences(); } if(indy) ctx_->llvm_state()->shared().gc_dependent(ctx_->llvm_state()); // Inject the RuntimeData objects used into the original CompiledCode // Do this way after we've validated the IR so things are consistent. void* native_function = ctx_->native_function(); ctx_->runtime_data_holder()->set_function(native_function, mci_->address(), mci_->size()); // info.method()->set_jit_data(ctx.runtime_data_holder()); ctx_->llvm_state()->shared().om->add_code_resource(ctx_->runtime_data_holder()); } return mci_->address(); }
void LLVMCompiler::compile(LLVMState* ls, VMMethod* vmm, bool is_block) { if(ls->config().jit_inline_debug) { if(is_block) { VMMethod* parent = vmm->parent(); assert(parent); llvm::errs() << "JIT: compiling block in " << ls->symbol_cstr(parent->original->scope()->module()->name()) << "#" << ls->symbol_cstr(vmm->original->name()) << " near " << ls->symbol_cstr(vmm->original->file()) << ":" << vmm->original->start_line() << "\n"; } else { llvm::errs() << "JIT: compiling " << ls->symbol_cstr(vmm->original->scope()->module()->name()) << "#" << ls->symbol_cstr(vmm->original->name()) << "\n"; } } JITMethodInfo info(vmm); info.is_block = is_block; LLVMWorkHorse work(ls, info); if(is_block) { work.setup_block(); } else { work.setup(); } llvm::Function* func = info.function(); if(!work.generate_body()) { function_ = NULL; // This is too noisy to report // llvm::outs() << "not supported yet.\n"; return; } if(ls->jit_dump_code() & cSimple) { llvm::outs() << "[[[ LLVM Simple IR ]]]\n"; llvm::outs() << *func << "\n"; } std::vector<BasicBlock*> to_remove; bool Broken = false; for(Function::iterator I = func->begin(), E = func->end(); I != E; ++I) { if(I->empty()) { BasicBlock& bb = *I; // No one jumps to it.... if(llvm::pred_begin(&bb) == llvm::pred_end(&bb)) { to_remove.push_back(&bb); } else { llvm::outs() << "Basic Block is empty and used!\n"; } } else if(!I->back().isTerminator()) { llvm::errs() << "Basic Block does not have terminator!\n"; llvm::errs() << *I << "\n"; llvm::errs() << "\n"; Broken = true; } } for(std::vector<BasicBlock*>::iterator i = to_remove.begin(); i != to_remove.end(); i++) { (*i)->eraseFromParent(); } if(Broken or llvm::verifyFunction(*func, PrintMessageAction)) { llvm::outs() << "ERROR: complication error detected.\n"; llvm::outs() << "ERROR: Please report the above message and the\n"; llvm::outs() << " code below to http://github.com/evanphx/rubinius/issues\n"; llvm::outs() << *func << "\n"; function_ = NULL; return; } ls->passes()->run(*func); if(ls->jit_dump_code() & cOptimized) { llvm::outs() << "[[[ LLVM Optimized IR: " << ls->symbol_cstr(vmm->original->name()) << " ]]]\n"; llvm::outs() << *func << "\n"; } function_ = func; }
void Compiler::compile_builder(jit::Context& ctx, LLVMState* ls, JITMethodInfo& info, jit::Builder& work) { llvm::Function* func = info.function(); if(!work.generate_body()) { function_ = NULL; // This is too noisy to report // llvm::outs() << "not supported yet.\n"; return; } // Hook up the return pad and return phi. work.generate_hard_return(); if(ls->jit_dump_code() & cSimple) { llvm::outs() << "[[[ LLVM Simple IR ]]]\n"; llvm::outs() << *func << "\n"; } std::vector<BasicBlock*> to_remove; bool Broken = false; for(Function::iterator I = func->begin(), E = func->end(); I != E; ++I) { if(I->empty()) { BasicBlock& bb = *I; // No one jumps to it.... if(llvm::pred_begin(&bb) == llvm::pred_end(&bb)) { to_remove.push_back(&bb); } else { llvm::outs() << "Basic Block is empty and used!\n"; } } else if(!I->back().isTerminator()) { llvm::errs() << "Basic Block does not have terminator!\n"; llvm::errs() << *I << "\n"; llvm::errs() << "\n"; Broken = true; } } for(std::vector<BasicBlock*>::iterator i = to_remove.begin(); i != to_remove.end(); ++i) { (*i)->eraseFromParent(); } if(Broken or llvm::verifyFunction(*func, PrintMessageAction)) { llvm::outs() << "ERROR: complication error detected.\n"; llvm::outs() << "ERROR: Please report the above message and the\n"; llvm::outs() << " code below to http://github.com/rubinius/rubinius/issues\n"; llvm::outs() << *func << "\n"; function_ = NULL; return; } ls->passes()->run(*func); if(ls->jit_dump_code() & cOptimized) { llvm::outs() << "[[[ LLVM Optimized IR: " << ls->symbol_cstr(info.method()->name()) << " ]]]\n"; llvm::outs() << *func << "\n"; } function_ = func; generate_function(ls); // Inject the RuntimeData objects used into the original CompiledMethod // Do this way after we've validated the IR so things are consistent. ctx.runtime_data_holder()->set_function(func, mci_->address(), mci_->size()); info.method()->set_jit_data(ctx.runtime_data_holder()); ls->shared().om->add_code_resource(ctx.runtime_data_holder()); }