JITMethodInfo::JITMethodInfo(jit::Context& ctx, CompiledCode* code, MachineCode* mcode, JITMethodInfo* parent) : context_(ctx) , entry_(0) , call_frame_(0) , stack_(0) , args_(0) , previous_(0) , profiling_entry_(0) , parent_info_(parent) , creator_info_(0) , use_full_scope_(false) , inline_block_(0) , block_info_(0) , method_(&ctx.state()->roots()) , return_pad_(0) , return_phi_(0) , self_class_(&ctx.state()->roots()) , machine_code(mcode) , is_block(false) , inline_return(0) , return_value(0) , inline_policy(0) , fin_block(0) , called_args(-1) , stack_args(0) , root(0) { method_.set(code); self_class_.set(nil<Object>()); }
JITMethodInfo::JITMethodInfo(jit::Context& ctx, CompiledMethod* cm, VMMethod* v, JITMethodInfo* parent) : context_(ctx) , function_(0) , entry_(0) , call_frame_(0) , stack_(0) , vm_(0) , args_(0) , previous_(0) , profiling_entry_(0) , out_args_(0) , counter_(0) , parent_info_(parent) , creator_info_(0) , use_full_scope_(false) , inline_block_(0) , block_info_(0) , method_(&ctx.state()->roots()) , vmm(v) , is_block(false) , inline_return(0) , return_value(0) , inline_policy(0) , fin_block(0) , called_args(-1) , stack_args(0) , root(0) { method_.set(cm); }
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()); }