bool AccessFrequency::runOnMachineFunction(MachineFunction &mf)
{	
    MF = &mf;
    MRI = &mf.getRegInfo();
    TRI = MF->getTarget().getRegisterInfo();
	m_nVars = 0;
	
	const llvm::Function *fn = mf.getFunction(); 
	std::string szMain = "main";
	if(fn->getName() != szMain && g_hFuncCall[szMain].find(fn->getName()) == g_hFuncCall[szMain].end() )
	{
		errs() << "--------qali:--------Skip function " << fn->getName() << " in AccessFrequency !\n";
		return true;
	}
    for (MachineFunction::const_iterator FI = MF->begin(), FE = MF->end();
       FI != FE; ++FI)
    {
		double dFactor = 0.0;
		const BasicBlock *bb = FI->getBasicBlock();
		if( bb != NULL )
		{
			//const std::map<const Function *, std::map<const BasicBlock *, double> > &hF2B2Acc =(SP->BlockInformation);
			std::map<const Function *, std::map<const BasicBlock *, double> >::const_iterator f2b2acc_p, E = g_hF2B2Acc->end();
			if( (f2b2acc_p = g_hF2B2Acc->find(fn) ) != E )
			{
				std::map<const BasicBlock *, double>::const_iterator b2acc_p, EE = f2b2acc_p->second.end();
				if( (b2acc_p = f2b2acc_p->second.find(bb) ) != EE )
					dFactor = b2acc_p->second;
			}
		}
		if( dFactor == 0.0 )
			dFactor = 1.0;
		
        for (MachineBasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end();
            BBI != BBE; ++BBI)
        {
			DEBUG(BBI->print(dbgs(), NULL ));
            //MachineInstr *MI = BBI;
            for (unsigned i = 0, e = BBI->getNumOperands(); i != e; ++ i)
            {
                const MachineOperand &MO = BBI->getOperand(i);
// TODO (qali#1#): To hack other kinds of MachineOperands
				switch (MO.getType() )
				{
				case MachineOperand::MO_Register:
					if( MO.getReg() != 0
						&& TargetRegisterInfo::isVirtualRegister(MO.getReg()) )
					{
						unsigned MOReg = MO.getReg();
						unsigned int nSize = getRegSize(MOReg);
						if( MO.isUse() )
						{					
							int nAcc = ROUND(dFactor);
							m_RegReadMap[MOReg] = m_RegReadMap[MOReg] + dFactor;
							//if( nAcc >= 1)
								m_SimTrace.push_back(llvm::TraceRecord(MOReg, nAcc));
						}
						else if( MO.isDef())
						{
							int nAcc = ROUND(dFactor);
							m_RegWriteMap[MOReg] = m_RegWriteMap[MOReg] + dFactor;
							//if( nAcc >= 1)
								m_SimTrace.push_back(llvm::TraceRecord(MOReg, nAcc, false));
						}
						else
							assert("Unrecoganized operation in AccessFrequency::runOnMachineFunction!\n");
					}
					break;
				default:
					break;
				}
            }

			// Analyze the memoperations
			if(!BBI->memoperands_empty() )
			{
				for( MachineInstr::mmo_iterator i = BBI->memoperands_begin(), e = BBI->memoperands_end();
					i != e; ++ i) {
						if( (*i)->isLoad() )
						{
							const char *tmp = (**i).getValue()->getName().data();

							m_StackReadMap[tmp] ++;
						}
						else if( (*i)->isStore())
						{
							const char *tmp = (**i).getValue()->getName().data();
							m_StackWriteMap[tmp] ++;
						}
						else
						{
							assert(false);
							 dbgs() << __FILE__ << __LINE__;
						}
					}
			}
        }
    }	
	m_nVars = m_RegReadMap.size();
    //print(afout);
	//printInt(afout);
	//reset();
	
	std::string szInfo;
	std::string szSrcFile = mf.getMMI().getModule()->getModuleIdentifier();	
	std::string szFile = szSrcFile + ".accInt";
	raw_fd_ostream accIfout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	printInt(accIfout);
	accIfout.close();
	
	szFile = szSrcFile + ".acc";
	raw_fd_ostream accfout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	print(accfout);
	accfout.close();
	
	szFile = szSrcFile + "." + "var";
	raw_fd_ostream varfout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	printVars(varfout);
	varfout.close();
	
	szFile = szSrcFile + ".read";
	raw_fd_ostream readfout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	printRead(readfout);
	readfout.close();
	
	szFile = szSrcFile + ".write";
	raw_fd_ostream writefout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	printWrite(writefout);
	writefout.close();

	szFile = szSrcFile + ".size";
	raw_fd_ostream sizefout(szFile.c_str(), szInfo, raw_fd_ostream::F_Append );
	printSize(sizefout);
	sizefout.close();
	
    return true;
}