virtual llvm::Value* materializeValueFor(llvm::Value* v) { // llvm::errs() << "materializing\n"; // v->dump(); llvm::Value* r = NULL; if (llvm::Function* f = llvm::dyn_cast<llvm::Function>(v)) { // llvm::errs() << "is function\n"; r = new_module->getOrInsertFunction(f->getName(), f->getFunctionType()); } else if (llvm::GlobalVariable* gv = llvm::dyn_cast<llvm::GlobalVariable>(v)) { // llvm::errs() << " is gv\n"; assert(gv->getLinkage() != llvm::GlobalVariable::PrivateLinkage); llvm::GlobalVariable* new_gv = llvm::cast<llvm::GlobalVariable>( new_module->getOrInsertGlobal(gv->getName(), gv->getType()->getElementType())); RELEASE_ASSERT(!gv->isThreadLocal(), "I don't think MCJIT supports thread-local variables yet"); new_gv->setThreadLocalMode(gv->getThreadLocalMode()); r = new_gv; } else if (llvm::GlobalAlias* alias = llvm::dyn_cast<llvm::GlobalAlias>(v)) { #if LLVMREV < 209040 llvm::Value* addressee = llvm::cast<llvm::Constant>(materializeValueFor(alias->getAliasedGlobal())); #else llvm::Value* addressee = llvm::cast<llvm::Constant>(materializeValueFor(alias->getAliasee())); #endif assert(addressee); assert(alias->getType() == addressee->getType()); r = addressee; // r = new llvm::GlobalAlias(alias->getType(), alias->getLinkage(), alias->getName(), addressee, // new_module); } else if (llvm::isa<llvm::Constant>(v)) { // llvm::errs() << " is a constant\n"; r = NULL; } else { r = v; } // if (r) // r->dump(); // llvm::errs() << "---\n"; return r; }
virtual llvm::Value* materializeValueFor(llvm::Value* v) { if (llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(v)) { llvm::PointerType* pt = llvm::dyn_cast<llvm::PointerType>(ce->getType()); if (ce->isCast() && ce->getOpcode() == llvm::Instruction::IntToPtr && pt) { llvm::ConstantInt* addr_const = llvm::cast<llvm::ConstantInt>(ce->getOperand(0)); void* addr = (void*)addr_const->getSExtValue(); bool lookup_success = true; std::string name; if (addr == (void*)None) { name = "None"; } else { name = g.func_addr_registry.getFuncNameAtAddress(addr, true, &lookup_success); } if (!lookup_success) return v; return module->getOrInsertGlobal(name, pt->getElementType()); } } return v; }
virtual llvm::Value* materializeValueFor(llvm::Value* v) { if (llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(v)) { llvm::PointerType* pt = llvm::dyn_cast<llvm::PointerType>(ce->getType()); if (ce->isCast() && ce->getOpcode() == llvm::Instruction::IntToPtr && pt) { llvm::ConstantInt* addr_const = llvm::cast<llvm::ConstantInt>(ce->getOperand(0)); void* addr = (void*)addr_const->getSExtValue(); bool lookup_success = true; std::string name; if (addr == (void*)None) { name = "None"; } else { name = g.func_addr_registry.getFuncNameAtAddress(addr, true, &lookup_success); } if (!lookup_success) return v; return module->getOrInsertGlobal(name, pt->getElementType()); } } if (llvm::IntrinsicInst* ii = llvm::dyn_cast<llvm::IntrinsicInst>(v)) { if (ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_i64 || ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_void || ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_double) { int pp_id = -1; for (int i = 0; i < ii->getNumArgOperands(); i++) { llvm::Value* op = ii->getArgOperand(i); if (i != 2) { if (i == 0) { llvm::ConstantInt* l_pp_id = llvm::cast<llvm::ConstantInt>(op); pp_id = l_pp_id->getSExtValue(); } ii->setArgOperand(i, llvm::MapValue(op, VMap, flags, type_remapper, this)); continue; } else { assert(pp_id != -1); void* addr = PatchpointInfo::getSlowpathAddr(pp_id); bool lookup_success = true; std::string name; if (addr == (void*)None) { name = "None"; } else { name = g.func_addr_registry.getFuncNameAtAddress(addr, true, &lookup_success); } if (!lookup_success) { llvm::Constant* int_val = llvm::ConstantInt::get(g.i64, reinterpret_cast<uintptr_t>(addr), false); llvm::Constant* ptr_val = llvm::ConstantExpr::getIntToPtr(int_val, g.i8); ii->setArgOperand(i, ptr_val); continue; } else { ii->setArgOperand(i, module->getOrInsertGlobal(name, g.i8)); } } } return ii; } } return v; }