void li_utostrn(char *buf, size_t buf_len, uintmax_t val) { char p_buf[LI_ITOSTRING_LENGTH]; char* const p_buf_end = p_buf + sizeof(p_buf); char* str = p_buf_end - 1; *str = '\0'; str = utostr(str, val); force_assert(p_buf_end > str && str >= p_buf); force_assert(buf_len >= (size_t) (p_buf_end - str)); memcpy(buf, str, p_buf_end - str); }
/** * Print a select instruction. * * @param cond the condition * @param trueVal the return value of the instruction if the condition is * non-zero * @param falseVal the return value of the instruction if the condition is * zero */ void JVMWriter::printSelectInstruction(const Value *cond, const Value *trueVal, const Value *falseVal) { std::string labelname = "select" + utostr(getUID()); printValueLoad(cond); printSimpleInstruction("ifeq", labelname + "a"); printValueLoad(trueVal); printSimpleInstruction("goto", labelname + "b"); printLabel(labelname + "a"); printValueLoad(falseVal); printLabel(labelname + "b"); }
Function* TwetoPassImpl::findFunction (sc_core::sc_module* initiatorMod, sc_core::sc_process_b* proc) { // compute the gnu-v3 mangled name of the function std::string fctName = proc->func_process; std::string modType = typeid(*initiatorMod).name(); std::string mainFctName = "_ZN" + modType + utostr(fctName.size()) + fctName + "Ev"; // Gets the function by its name (dlsym equivalent) Function *f = this->llvmMod->getFunction(mainFctName); return f; }
void BrainFTraceRecorder::compile(BrainFTraceNode* trace) { LLVMContext &Context = module->getContext(); // Create a new function for the trace we're compiling. Function *curr_func = Function::Create(op_type, Function::ExternalLinkage, "", module); // Create an entry block, which branches directly to a header block. // This is necessary because the entry block cannot be the target of // a loop. BasicBlock *Entry = BasicBlock::Create(Context, "entry", curr_func); Header = BasicBlock::Create(Context, utostr(trace->pc), curr_func); // Mark the array pointer as noalias, and setup compiler state. IRBuilder<> builder(Entry); Argument *Arg1 = ++curr_func->arg_begin(); Arg1->addAttr(Attribute::NoAlias); DataPtr = Arg1; // Emit code to set the mode flag. This signals to the recorder // that the preceding opcode was executed as a part of a compiled trace. const IntegerType *flag_type = IntegerType::get(Context, 8); ConstantInt *Mode = ConstantInt::get(flag_type, MODE_EXTENSION_BEGIN); builder.CreateStore(Mode, mode_flag); // Emit code to set the extension root, which is a pointer to the // root of the trace tree. ConstantInt *ExtRoot = ConstantInt::get(int_type, (intptr_t)trace); builder.CreateStore(ExtRoot, ext_root); builder.CreateBr(Header); // Header will be the root of our trace tree. As such, all loop back-edges // will be targetting it. Setup a PHI node to merge together incoming values // for the current array pointer as we loop. builder.SetInsertPoint(Header); HeaderPHI = builder.CreatePHI(DataPtr->getType()); HeaderPHI->addIncoming(DataPtr, Entry); DataPtr = HeaderPHI; // Recursively descend the trace tree, emitting code for the opcodes as we go. compile_opcode(trace, builder); // Run out optimization suite on our newly generated trace. FPM->run(*curr_func); // Compile our trace to machine code, and install function pointer to it // into the bytecode array so that it will be executed every time the // trace-head PC is reached. void *code = EE->getPointerToFunction(curr_func); BytecodeArray[trace->pc] = (opcode_func_t)(intptr_t)code; }
/** * Load the given value. * * @param v the value to load */ void JVMWriter::printValueLoad(const Value *v) { if(const Function *f = dyn_cast<Function>(v)) { std::string sig = getValueName(f) + getCallSignature(f->getFunctionType()); if(externRefs.count(v)) printSimpleInstruction("CLASSFORMETHOD", sig); else printSimpleInstruction("ldc", '"' + classname + '"'); printSimpleInstruction("ldc", '"' + sig + '"'); printSimpleInstruction("invokestatic", "lljvm/runtime/Function/getFunctionPointer" "(Ljava/lang/String;Ljava/lang/String;)I"); } else if(isa<GlobalVariable>(v)) { const Type *ty = cast<PointerType>(v->getType())->getElementType(); if(externRefs.count(v)) printSimpleInstruction("getstatic", getValueName(v) + " I"); else printSimpleInstruction("getstatic", classname + "/" + getValueName(v) + " I"); } else if(isa<ConstantPointerNull>(v)) { printPtrLoad(0); } else if(const ConstantExpr *ce = dyn_cast<ConstantExpr>(v)) { printConstantExpr(ce); } else if(const Constant *c = dyn_cast<Constant>(v)) { printConstLoad(c); } else { if(getLocalVarNumber(v) <= 3) printSimpleInstruction( getTypePrefix(v->getType(), true) + "load_" + utostr(getLocalVarNumber(v)) + " ; " + getValueName(v)); else printSimpleInstruction( getTypePrefix(v->getType(), true) + "load", utostr(getLocalVarNumber(v)) + " ; " + getValueName(v)); } }
void BipartiteWeightedMatchingBinding::UpdateAssignments(raw_ostream &out, int numOperationsToShare, std::string funcUnitType, int numFuncUnitsAvail, AssignmentInfo &assigned, Table &assignments) { std::string s; std::stringstream ss; // Note that assignments (and weights) are square matrices, // numFuncUnitsAvail x numFuncUnitsAvail // However, numOperationsToShare <= numFuncUnitsAvail so the iteration // below is within bounds assert(numOperationsToShare <= numFuncUnitsAvail); for (int fu = 0; fu < numFuncUnitsAvail; fu++) { for (int o = 0; o < numOperationsToShare; o++) { if (assignments[fu][o]) { Instruction *I = opInstr[o]; std::string fuId = this->alloc->verilogNameFunction(this->Fp, this->Fp) + "_" + funcUnitType + "_" + utostr(fu); this->BindingInstrFU[I] = fuId; int numOperands = 0; for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) { Instruction *operand = dyn_cast<Instruction>(*i); numOperands++; if (!operand) continue; if (assigned.existingOperands[fuId].find(operand) == assigned.existingOperands[fuId].end()) { assigned.existingOperands[fuId].insert(operand); assigned.muxInputs[fuId]++; } } std::string instStr = getValueStr(opInstr[o]); limitString(instStr, 30); ss << instStr << " (idx: " << o << ") -> " << fuId << " (mux inputs: " << assigned.muxInputs[fuId] << ")\n"; // number of operands for mem_dual_port is not 2 //assert(numOperands == 2); assigned.existingInstructions[fuId].insert(I); } } } ss.flush(); out << ss.str(); }
/** * Return the name of the given value. * * @param v the value * @return the name of the value */ std::string JVMWriter::getValueName(const Value *v) { if(const GlobalValue *gv = dyn_cast<GlobalValue>(v)) return sanitizeName(Mangler(MCAsmInfo()).getNameWithPrefix(gv)); if(v->hasName()) return '_' + sanitizeName(v->getName()); if(localVars.count(v)) { unsigned int tid; if (temporaryNames.count(v)) tid = temporaryNames[v]; else { tid = temporaryNames.size(); temporaryNames[v] = tid; } return "$" + utostr(tid); } return "_"; }
void ARMAttributeParser::ABI_align_needed(AttrType Tag, const uint8_t *Data, uint32_t &Offset) { static const char *Strings[] = { "Not Permitted", "8-byte alignment", "4-byte alignment", "Reserved" }; uint64_t Value = ParseInteger(Data, Offset); std::string Description; if (Value < array_lengthof(Strings)) Description = std::string(Strings[Value]); else if (Value <= 12) Description = std::string("8-byte alignment, ") + utostr(1 << Value) + std::string("-byte extended alignment"); else Description = "Invalid"; PrintAttribute(Tag, Value, Description); }
/** * Print a vararg intrinsic function. * * @param inst the instruction */ void JVMWriter::printVAIntrinsic(const IntrinsicInst *inst) { const Type *valistTy = PointerType::getUnqual( IntegerType::get(inst->getContext(), 8)); switch(inst->getIntrinsicID()) { case Intrinsic::vastart: printLoadMemoryToStack( ); printValueLoad(inst->getOperand(1)); printSimpleInstruction("iload", utostr(vaArgNum) + " ; varargptr"); printIndirectStore(valistTy); break; case Intrinsic::vacopy: printLoadMemoryToStack( ); printValueLoad(inst->getOperand(1)); printValueLoad(inst->getOperand(2)); printIndirectLoad(valistTy); printIndirectStore(valistTy); break; case Intrinsic::vaend: break; } }
static char* itostr(char * const buf_end, intmax_t val) { char *cur = buf_end; if (val >= 0) return utostr(buf_end, (uintmax_t) val); /* can't take absolute value, as it isn't defined for INTMAX_MIN */ do { int mod = val % 10; val /= 10; /* val * 10 + mod == orig val, -10 < mod < 10 */ /* we want a negative mod */ if (mod > 0) { mod -= 10; val += 1; } /* prepend digit abs(mod) */ *(--cur) = (char) ('0' + (-mod)); } while (0 != val); *(--cur) = '-'; return cur; }
unsigned char play_game(void) { unsigned char guess, lo = 0, hi = 255; unsigned char *read; unsigned int len; char buf[10]; // I'm thinking of a magic number, can you guess it ?!?!\n delimited_read(STDIN, &read, &len, (unsigned char *)"\n", 1); free(read); while (1) { guess = (lo + hi) / 2; utostr(guess, 10, 0, buf, sizeof(buf)); transmit_all(STDOUT, buf, strlen(buf)); transmit_all(STDOUT, "\n", 1); delimited_read(STDIN, &read, &len, (unsigned char *)"\n", 1); if (strncmp((char *)read, "Just right!\n", len) == 0) break; else if (strncmp((char *)read, "Haha, too small!\n", len) == 0) lo = guess + 1; else if (strncmp((char *)read, "Whoa, too big\n", len) == 0) hi = guess - 1; free(read); // WRONG!\n delimited_read(STDIN, &read, &len, (unsigned char *)"\n", 1); free(read); } free(read); return guess; }
void BipartiteWeightedMatchingBinding::constructWeights(raw_ostream &out, Instruction *I, int operationIdx, std::string funcUnitType, int numFuncUnitsAvail, AssignmentInfo &assigned, Table &weights) { int existingMuxInputsFactor = 1; int newMuxInputsFactor = 10; // note: this is negative, a shared output register reduces the cost int outputRegisterSharableFactor = -5; for (int fu = 0; fu < numFuncUnitsAvail; fu++) { int weight = 0; std::string fuId = this->alloc->verilogNameFunction(this->Fp, this->Fp) + "_" + funcUnitType + "_" + utostr(fu); // check both operands for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) { Instruction *operand = dyn_cast<Instruction>(*i); if (!operand) continue; if (assigned.existingOperands[fuId].find(operand) == assigned.existingOperands[fuId].end()) { weight += newMuxInputsFactor; } else { std::string instStr = getValueStr(I); limitString(instStr, 30); out << instStr << " can share an input with another operation " "already assigned to " << fuId << "\n"; } } bool outputRegSharable = false; for (set<Instruction*>::iterator i = assigned.existingInstructions[fuId].begin(), e = assigned.existingInstructions[fuId].end(); i != e; ++i) { Instruction *shared = *i; // check for shared output register if (assigned.IndependentInstructions[I].find(shared) != assigned.IndependentInstructions[I].end() ) { //errs() << "Shared output: " << *shared << "\n"; outputRegSharable = true; break; } } if (outputRegSharable) { weight += outputRegisterSharableFactor; std::string instStr = getValueStr(I); limitString(instStr, 30); out << instStr << " can share an output register with another " "operation already assigned to " << fuId << "\n"; } weight += existingMuxInputsFactor * assigned.muxInputs[fuId]; weights[fu][operationIdx] = weight; //errs() << "weight " << fu << " " << operationIdx << " = " << // weights[fu][operationIdx] << "\n"; } }
/** * Return the label name of the given block. * * @param block the block * @return the label */ std::string JVMWriter::getLabelName(const BasicBlock *block) { if(!blockIDs.count(block)) blockIDs[block] = blockIDs.size() + 1; return sanitizeName("label" + utostr(blockIDs[block])); }
/// compile_if - Emit code for '[' void BrainFTraceRecorder::compile_if(BrainFTraceNode *node, IRBuilder<>& builder) { BasicBlock *ZeroChild = 0; BasicBlock *NonZeroChild = 0; BasicBlock *Parent = builder.GetInsertBlock(); LLVMContext &Context = Header->getContext(); // If both directions of the branch go back to the trace-head, just // jump there directly. if (node->left == (BrainFTraceNode*)~0ULL && node->right == (BrainFTraceNode*)~0ULL) { HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock()); builder.CreateBr(Header); return; } // Otherwise, there are two cases to handle for each direction: // ~0ULL - A branch back to the trace head // 0 - A branch out of the trace // * - A branch to a node we haven't compiled yet. // Go ahead and generate code for both targets. if (node->left == (BrainFTraceNode*)~0ULL) { NonZeroChild = Header; HeaderPHI->addIncoming(DataPtr, Parent); } else if (node->left == 0) { NonZeroChild = BasicBlock::Create(Context, "exit_left_"+utostr(node->pc), Header->getParent()); builder.SetInsertPoint(NonZeroChild); // Set the extension leaf, which is a pointer to the leaf of the trace // tree from which we are side exiting. ConstantInt *ExtLeaf = ConstantInt::get(int_type, (intptr_t)node); builder.CreateStore(ExtLeaf, ext_leaf); ConstantInt *NewPc = ConstantInt::get(int_type, node->pc+1); Value *BytecodeIndex = builder.CreateConstInBoundsGEP1_32(bytecode_array, node->pc+1); Value *Target = builder.CreateLoad(BytecodeIndex); CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr)); Call->setTailCall(); builder.CreateRetVoid(); } else { NonZeroChild = BasicBlock::Create(Context, utostr(node->left->pc), Header->getParent()); builder.SetInsertPoint(NonZeroChild); compile_opcode(node->left, builder); } if (node->right == (BrainFTraceNode*)~0ULL) { ZeroChild = Header; HeaderPHI->addIncoming(DataPtr, Parent); } else if (node->right == 0) { ZeroChild = BasicBlock::Create(Context, "exit_right_"+utostr(node->pc), Header->getParent()); builder.SetInsertPoint(ZeroChild); // Set the extension leaf, which is a pointer to the leaf of the trace // tree from which we are side exiting. ConstantInt *ExtLeaf = ConstantInt::get(int_type, (intptr_t)node); builder.CreateStore(ExtLeaf, ext_leaf); ConstantInt *NewPc = ConstantInt::get(int_type, JumpMap[node->pc]+1); Value *BytecodeIndex = builder.CreateConstInBoundsGEP1_32(bytecode_array, JumpMap[node->pc]+1); Value *Target = builder.CreateLoad(BytecodeIndex); CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr)); Call->setTailCall(); builder.CreateRetVoid(); } else { ZeroChild = BasicBlock::Create(Context, utostr(node->right->pc), Header->getParent()); builder.SetInsertPoint(ZeroChild); compile_opcode(node->right, builder); } // Generate the test and branch to select between the targets. builder.SetInsertPoint(Parent); Value *Loaded = builder.CreateLoad(DataPtr); Value *Cmp = builder.CreateICmpEQ(Loaded, ConstantInt::get(Loaded->getType(), 0)); builder.CreateCondBr(Cmp, ZeroChild, NonZeroChild); }
/* * Special format: * "%*s", number, string : print number-width string */ int vsprintf(char *buf, char *fmt, va_list args) { char *dst = buf; unsigned int u; /* value for %u/%x */ int d; /* value for %d */ char *s; /* value for %s */ void *p; /* value for %p */ int zero; /* completion with 0 */ int width; /* width field */ int left; /* left aligned */ int len; /* parsed string length */ int swidth; /* special format: %*s */ while (*fmt) { if (*fmt != '%') { *dst++ = *fmt++; continue; } fmt++; /* skip '%' */ zero = 0; width = 0; swidth = 0; left = 0; /* handle alignment direction */ while (*fmt == '+' || *fmt == '-') { left = (*fmt == '-'); fmt++; } /* handle width */ while (*fmt == '0') { /* 0 completion */ zero = 1; fmt++; } if (*fmt >= '1' && *fmt <= '9') width = strtoi(fmt, &fmt, 10); /* handle undefinite width of string */ if (*fmt == '*') { swidth = va_arg(args, int); width = 0; /* zero standard width */ fmt++; } /* handle format char */ switch (*fmt) { case '%': *dst = '%'; len = 1; break; case 'c': *dst = va_arg(args, char); len = 1; break; case 'd': d = va_arg(args, int); len = itostr(d, dst, 10); break; case 'u': u = va_arg(args, unsigned int); len = utostr(u, dst, 10); break; case 'x': u = va_arg(args, unsigned int); len = utostr(u, dst, 16); break; case 'p': p = va_arg(args, void *); *dst++ = '0'; *dst++ = 'x'; len = utostr((unsigned int)p, dst, 16); break; case 's': s = va_arg(args, char *); if (swidth > 0) len = strnncpy(dst, s, swidth); else len = strcpy(dst, s); break; } if (width > len) { if (left) { memset(dst + len, ' ', width - len); } else { memmove(dst + width - len, dst, len); memset(dst, zero ? '0' : ' ', width - len); } len = width; } fmt++; dst += len; }
std::string BlockToString(CBlockIndex* pBlock) { if (!pBlock) return ""; CBlock block; ReadBlockFromDisk(block, pBlock); CAmount Fees = 0; CAmount OutVolume = 0; CAmount Reward = 0; std::string TxLabels[] = {_("Hash"), _("From"), _("Amount"), _("To"), _("Amount")}; std::string TxContent = table + makeHTMLTableRow(TxLabels, sizeof(TxLabels) / sizeof(std::string)); for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction& tx = block.vtx[i]; TxContent += TxToRow(tx); CAmount In = getTxIn(tx); CAmount Out = tx.GetValueOut(); if (tx.IsCoinBase()) Reward += Out; else if (In < 0) Fees = -Params().MaxMoneyOut(); else { Fees += In - Out; OutVolume += Out; } } TxContent += "</table>"; CAmount Generated; if (pBlock->nHeight == 0) Generated = OutVolume; else Generated = GetBlockValue(pBlock->nHeight - 1); std::string BlockContentCells[] = { _("Height"), itostr(pBlock->nHeight), _("Size"), itostr(GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)), _("Number of Transactions"), itostr(block.vtx.size()), _("Value Out"), ValueToString(OutVolume), _("Fees"), ValueToString(Fees), _("Generated"), ValueToString(Generated), _("Timestamp"), TimeToString(block.nTime), _("Difficulty"), strprintf("%.4f", GetDifficulty(pBlock)), _("Bits"), utostr(block.nBits), _("Nonce"), utostr(block.nNonce), _("Version"), itostr(block.nVersion), _("Hash"), "<pre>" + block.GetHash().GetHex() + "</pre>", _("Merkle Root"), "<pre>" + block.hashMerkleRoot.GetHex() + "</pre>", // _("Hash Whole Block"), "<pre>" + block.hashWholeBlock.GetHex() + "</pre>" // _("Miner Signature"), "<pre>" + block.MinerSignature.ToString() + "</pre>" }; std::string BlockContent = makeHTMLTable(BlockContentCells, sizeof(BlockContentCells) / (2 * sizeof(std::string)), 2); std::string Content; Content += "<h2><a class=\"nav\" href="; Content += itostr(pBlock->nHeight - 1); Content += ">◄ </a>"; Content += _("Block"); Content += " "; Content += itostr(pBlock->nHeight); Content += "<a class=\"nav\" href="; Content += itostr(pBlock->nHeight + 1); Content += "> ►</a></h2>"; Content += BlockContent; Content += "</br>"; /* if (block.nHeight > getThirdHardforkBlock()) { std::vector<std::string> votes[2]; for (int i = 0; i < 2; i++) { for (unsigned int j = 0; j < block.vvotes[i].size(); j++) { votes[i].push_back(block.vvotes[i][j].hash.ToString() + ':' + itostr(block.vvotes[i][j].n)); } } Content += "<h3>" + _("Votes +") + "</h3>"; Content += makeHTMLTable(&votes[1][0], votes[1].size(), 1); Content += "</br>"; Content += "<h3>" + _("Votes -") + "</h3>"; Content += makeHTMLTable(&votes[0][0], votes[0].size(), 1); Content += "</br>"; } */ Content += "<h2>" + _("Transactions") + "</h2>"; Content += TxContent; return Content; }
// ============================================================================= // replaceCallsInProcess // // Replace indirect calls to write() or read() by direct calls // in the given process. // ============================================================================= void TLMBasicPassImpl::replaceCallsInProcess(sc_core::sc_module *initiatorMod, sc_core::sc_process_b *proc) { // Get associate function std::string fctName = proc->func_process; std::string modType = typeid(*initiatorMod).name(); std::string mainFctName = "_ZN" + modType + utostr(fctName.size()) + fctName + "Ev"; Function *oldProcf = this->llvmMod->getFunction(mainFctName); if (oldProcf==NULL) return; // We do not modifie the original function // Instead, we create a clone. Function *procf = createProcess(oldProcf, initiatorMod); void *funPtr = this->engine->getPointerToFunction(procf); sc_core::SC_ENTRY_FUNC_OPT scfun = reinterpret_cast<sc_core::SC_ENTRY_FUNC_OPT>(funPtr); proc->m_semantics_p = scfun; std::string procfName = procf->getName(); MSG(" Replace in the process's function : "+procfName+"\n"); std::ostringstream oss; sc_core::sc_module *targetMod; std::vector<CallInfo*> *work = new std::vector<CallInfo*>; inst_iterator ii; for (ii = inst_begin(procf); ii!=inst_end(procf); ii++) { Instruction &i = *ii; CallSite cs(&i); if (cs.getInstruction()) { // Candidate for a replacement Function *oldfun = cs.getCalledFunction(); if (oldfun!=NULL && !oldfun->isDeclaration()) { std::string name = oldfun->getName(); // === Write === if (!strcmp(name.c_str(), wFunName.c_str())) { CallInfo *info = new CallInfo(); info->oldcall = dyn_cast<CallInst>(cs.getInstruction()); MSG(" Checking adress : "); // Retrieve the adress argument by executing // the appropriated piece of code SCJit *scjit = new SCJit(this->llvmMod, this->elab); Process *irProc = this->elab->getProcess(proc); scjit->setCurrentProcess(irProc); bool jitErr = false; info->addrArg = cs.getArgument(1); int value = scjit->jitInt(procf, info->oldcall, info->addrArg, &jitErr); if(jitErr) { std::cout << " cannot get the address value!" << std::endl; } else { oss.str(""); oss << std::hex << value; MSG("0x"+oss.str()+"\n"); basic::addr_t a = static_cast<basic::addr_t>(value); // Checking address alignment if(value % sizeof(basic::data_t)) { std::cerr << " unaligned write : " << std::hex << value << std::endl; abort(); } // Retreive the target module using the address targetMod = getTargetModule(initiatorMod, a); // Save informations to build a new call later FunctionType *writeFunType = this->basicWriteFun->getFunctionType(); info->targetType = writeFunType->getParamType(0); LLVMContext &context = getGlobalContext(); IntegerType *intType; if (this->is64Bit) { intType = Type::getInt64Ty(context); } else { intType = Type::getInt32Ty(context); } info->targetModVal = ConstantInt::getSigned(intType, reinterpret_cast<intptr_t>(targetMod)); info->dataArg = cs.getArgument(2); work->push_back(info); } } else // === Read === if (!strcmp(name.c_str(), rFunName.c_str())) { // Not yet supported } } } } // Before //procf->dump(); // Replace calls std::vector<CallInfo*>::iterator it; for (it = work->begin(); it!=work->end(); ++it) { CallInfo *i = *it; LLVMContext &context = getGlobalContext(); FunctionType *writeFunType = this->writeFun->getFunctionType(); IntegerType *i64 = Type::getInt64Ty(context); // Get a pointer to the target module basic::target_module_base *tmb = dynamic_cast<basic::target_module_base*>(targetMod); Value *ptr = ConstantInt::getSigned(i64, reinterpret_cast<intptr_t>(tmb)); IntToPtrInst *modPtr = new IntToPtrInst(ptr, writeFunType->getParamType(0), "myitp", i->oldcall); // Get a the address value LoadInst *addr = new LoadInst(i->addrArg, "", i->oldcall); // Create the new call Value *args[] = {modPtr, addr, i->dataArg}; i->newcall = CallInst::Create(this->writeFun, ArrayRef<Value*>(args, 3)); // Replace the old call BasicBlock::iterator it(i->oldcall); ReplaceInstWithInst(i->oldcall->getParent()->getInstList(), it, i->newcall); i->oldcall->replaceAllUsesWith(i->newcall); // Inline the new call DataLayout *td = new DataLayout(this->llvmMod); InlineFunctionInfo ifi(NULL, td); bool success = InlineFunction(i->newcall, ifi); if(!success) { MSG(" The call cannot be inlined (it's not an error :D)"); } MSG(" Call optimized (^_-)\n"); callOptCounter++; } //std::cout << "==================================\n"; // Run preloaded passes on the function to propagate constants funPassManager->run(*procf); // After //procf->dump(); // Check if the function is corrupt verifyFunction(*procf); this->engine->recompileAndRelinkFunction(procf); }