void BlockBuilder::setup() { std::vector<const Type*> ftypes; ftypes.push_back(ls_->ptr_type("VM")); ftypes.push_back(ls_->ptr_type("CallFrame")); ftypes.push_back(ls_->ptr_type("BlockEnvironment")); ftypes.push_back(ls_->ptr_type("Arguments")); ftypes.push_back(ls_->ptr_type("BlockInvocation")); FunctionType* ft = FunctionType::get(ls_->ptr_type("Object"), ftypes, false); std::stringstream ss; ss << std::string("_X_") << ls_->enclosure_name(info_.method()) << "#" << ls_->symbol_cstr(info_.method()->name()) << "$block@" << ls_->add_jitted_method(); func = Function::Create(ft, GlobalValue::ExternalLinkage, ss.str().c_str(), ls_->module()); Function::arg_iterator ai = func->arg_begin(); vm = ai++; vm->setName("state"); prev = ai++; prev->setName("previous"); block_env = ai++; block_env->setName("env"); args = ai++; args->setName("args"); block_inv = ai++; block_inv->setName("invocation"); BasicBlock* block = BasicBlock::Create(ls_->ctx(), "entry", func); b().SetInsertPoint(block); info_.set_function(func); info_.set_vm(vm); info_.set_args(args); info_.set_previous(prev); info_.set_entry(block); BasicBlock* body = BasicBlock::Create(ls_->ctx(), "block_body", func); pass_one(body); info_.set_counter(b().CreateAlloca(ls_->Int32Ty, 0, "counter_alloca")); counter2_ = b().CreateAlloca(ls_->Int32Ty, 0, "counter2"); // The 3 here is because we store {ip, sp, type} per unwind. info_.set_unwind_info(b().CreateAlloca(ls_->Int32Ty, ConstantInt::get(ls_->Int32Ty, rubinius::kMaxUnwindInfos * 3), "unwind_info")); valid_flag = b().CreateAlloca(ls_->Int1Ty, 0, "valid_flag"); Value* cfstk = b().CreateAlloca(obj_type, ConstantInt::get(ls_->Int32Ty, (sizeof(CallFrame) / sizeof(Object*)) + vmm_->stack_size), "cfstk"); call_frame = b().CreateBitCast( cfstk, llvm::PointerType::getUnqual(cf_type), "call_frame"); info_.set_out_args(b().CreateAlloca(ls_->type("Arguments"), 0, "out_args")); if(ls_->include_profiling()) { method_entry_ = b().CreateAlloca(ls_->Int8Ty, ConstantInt::get(ls_->Int32Ty, sizeof(tooling::MethodEntry)), "method_entry"); info_.set_profiling_entry(method_entry_); } info_.set_call_frame(call_frame); stk = b().CreateConstGEP1_32(cfstk, sizeof(CallFrame) / sizeof(Object*), "stack"); info_.set_stack(stk); Value* var_mem = b().CreateAlloca(obj_type, ConstantInt::get(ls_->Int32Ty, (sizeof(StackVariables) / sizeof(Object*)) + vmm_->number_of_locals), "var_mem"); vars = b().CreateBitCast( var_mem, llvm::PointerType::getUnqual(stack_vars_type), "vars"); info_.set_variables(vars); initialize_frame(vmm_->stack_size); nil_stack(vmm_->stack_size, constant(Qnil, obj_type)); setup_block_scope(); if(ls_->config().version >= 19) { import_args_19_style(); } if(ls_->include_profiling()) { Value* test = b().CreateLoad(ls_->profiling(), "profiling"); BasicBlock* setup_profiling = BasicBlock::Create(ls_->ctx(), "setup_profiling", func); BasicBlock* cont = BasicBlock::Create(ls_->ctx(), "continue", func); b().CreateCondBr(test, setup_profiling, cont); b().SetInsertPoint(setup_profiling); Signature sig(ls_, ls_->VoidTy); sig << "VM"; sig << llvm::PointerType::getUnqual(ls_->Int8Ty); sig << "BlockEnvironment"; sig << "Module"; sig << "CompiledMethod"; Value* call_args[] = { vm, method_entry_, block_env, module_, method }; sig.call("rbx_begin_profiling_block", call_args, 5, "", b()); b().CreateBr(cont); b().SetInsertPoint(cont); } b().CreateBr(body); b().SetInsertPoint(body); }
void BlockBuilder::setup() { std::vector<const Type*> ftypes; ftypes.push_back(ls_->ptr_type("VM")); ftypes.push_back(ls_->ptr_type("CallFrame")); ftypes.push_back(ls_->ptr_type("BlockEnvironment")); ftypes.push_back(ls_->ptr_type("Arguments")); ftypes.push_back(ls_->ptr_type("BlockInvocation")); FunctionType* ft = FunctionType::get(ls_->ptr_type("Object"), ftypes, false); std::ostringstream ss; ss << std::string("_X_") << ls_->enclosure_name(info_.method()) << "#" << ls_->symbol_debug_str(info_.method()->name()) << "$block@" << ls_->add_jitted_method(); llvm::Function* func = Function::Create(ft, GlobalValue::ExternalLinkage, ss.str().c_str(), ls_->module()); Function::arg_iterator ai = func->arg_begin(); llvm::Value* vm = ai++; vm->setName("state"); llvm::Value* prev = ai++; prev->setName("previous"); block_env = ai++; block_env->setName("env"); llvm::Value* args = ai++; args->setName("args"); block_inv = ai++; block_inv->setName("invocation"); BasicBlock* block = BasicBlock::Create(ls_->ctx(), "entry", func); b().SetInsertPoint(block); info_.context().set_function(func); info_.set_vm(vm); info_.set_args(args); info_.set_previous(prev); info_.set_entry(block); alloc_frame("block_body"); initialize_frame(vmm_->stack_size); nil_stack(vmm_->stack_size, constant(Qnil, obj_type)); setup_block_scope(); if(ls_->config().version >= 19) { import_args_19_style(); } if(ls_->include_profiling()) { Value* test = b().CreateLoad(ls_->profiling(), "profiling"); BasicBlock* setup_profiling = BasicBlock::Create(ls_->ctx(), "setup_profiling", func); BasicBlock* cont = BasicBlock::Create(ls_->ctx(), "continue", func); b().CreateCondBr(test, setup_profiling, cont); b().SetInsertPoint(setup_profiling); Signature sig(ls_, ls_->VoidTy); sig << "VM"; sig << llvm::PointerType::getUnqual(ls_->Int8Ty); sig << "BlockEnvironment"; sig << "Module"; sig << "CompiledMethod"; Value* call_args[] = { vm, method_entry_, block_env, module_, method }; sig.call("rbx_begin_profiling_block", call_args, 5, "", b()); b().CreateBr(cont); b().SetInsertPoint(cont); } b().CreateBr(body_); b().SetInsertPoint(body_); }