Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
/**
 * 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");
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
/**
 * 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();
}
Ejemplo n.º 7
0
/**
 * 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 "_";
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
/**
 * 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;
    }
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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";
    }
}
Ejemplo n.º 13
0
/**
 * 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]));
}
Ejemplo n.º 14
0
/// 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);
}
Ejemplo n.º 15
0
/*
 * 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;
	}
Ejemplo n.º 16
0
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 += ">◄&nbsp;</a>";
    Content += _("Block");
    Content += " ";
    Content += itostr(pBlock->nHeight);
    Content += "<a class=\"nav\" href=";
    Content += itostr(pBlock->nHeight + 1);
    Content += ">&nbsp;►</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);
}