Index: jitrino/src/codegenerator/ia32/Ia32IRXMLDump.cpp =================================================================== --- jitrino/src/codegenerator/ia32/Ia32IRXMLDump.cpp (revision 0) +++ jitrino/src/codegenerator/ia32/Ia32IRXMLDump.cpp (revision 0) @@ -0,0 +1,259 @@ + +#include "Ia32IRXMLDump.h" +#include +#include + + +using namespace std; +using std::endl; +using std::ostream; + + +namespace Jitrino +{ +namespace Ia32 +{ + + +static void strcode (string& s) +{ + string::size_type offs; + + for (offs = 0; (offs = s.find_first_of('<', offs)) != string::npos;) + s.replace(offs, 1, "<"); + + for (offs = 0; (offs = s.find_first_of('>', offs)) != string::npos;) + s.replace(offs, 1, ">"); +} + + +//======================================================================================== +// class IRXMLDump +//======================================================================================== + + +IRXMLDump::IRXMLDump (const IRManager& x, ostream* s) +: irm(x), os(s), mm(1000, "IRDump"), splits(mm) +{ + if (os != 0) + *os << "" << endl; +} + + +IRXMLDump::~IRXMLDump () +{ +} + + +void IRXMLDump::split (const Opnd* parent, const Opnd* child) +{ + splits.push_back(parent); + splits.push_back(child); +} + + +void IRXMLDump::write () +{ + if (os != 0) + { + MethodDesc& md = irm.getMethodDesc(); + + ostringstream sbuff; + sbuff << md.getParentType()->getName() << "." << md.getName() + << md.getSignatureString(); + + string str(sbuff.str()); + strcode(str); + *os << "" << endl; + + writeOpnds(); + writeCFG(); + + *os << "" << endl; + } +} + + +void IRXMLDump::writeOpnds () +{ + *os << "" << endl; + for (int i = irm.getOpndCount(); --i != -1;) + { + const Opnd* opnd = irm.getOpnd(i); + *os << "getFirstId() << "\" cid=\"" << opnd->getId(); + + Constraint loc = opnd->getConstraint(Opnd::ConstraintKind_Location); + if (!loc.isNull()) + {// this operand is already assigned to some location/register + *os << "\" loc=\""; + + RegName rn = opnd->getRegName(); + if (rn != RegName_Null) + *os << getRegNameString(rn); + else if (opnd->isPlacedIn(OpndKind_Memory)) + *os << "mem"; + else if (opnd->isPlacedIn(OpndKind_Immediate)) + *os << "imm"; + else + *os << "?"; + } + + *os << "\"/>" << endl; + } + + for (StlVector::const_iterator it = splits.begin(); it != splits.end();) + { + const Opnd* parent = *it++; + const Opnd* child = *it++; + *os << "getFirstId() + << "\" idchild=\"" << child->getFirstId() + << "\"/>" << endl; + } + *os << "" << endl; +} + + +void IRXMLDump::writeCFG () +{ + *os << "" << endl; + + const Nodes& nodes = irm.getFlowGraph()->getNodes(); + for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) + { + const Node* node = *it; + + *os << "getId() << "\""; + + *os << " kind=\""; + if (node->isBlockNode()) + *os << "BasicBlock\""; + else if (node->isDispatchNode()) + *os << "DispatchNode\""; + else if (node->isExitNode()) + *os << "ExitNode\""; + else + *os << "?\""; + + writeEdges(true, node); + writeEdges(false, node); + +// if (node->isLoopHeader() +// *os << " LoopHeader=\"TRUE\""; + + *os << ">" << endl; + + if (node->isBlockNode()) + writeNode(static_cast(node)); + + *os << "" << endl; + } + + *os << "" << endl; +} + + +void IRXMLDump::writeEdges (bool in, const Node* node) +{ + int count = 0; + const Edges& es = in ? node->getInEdges() : node->getOutEdges(); + for (Edges::const_iterator it = es.begin(), end = es.end(); it != end; ++it) + { + const Edge* e = *it; + if (count++ == 0) + *os << (in ? " pred=\"" : " succ=\""); + else + *os << ","; + + *os << (in ? e->getSourceNode() : e->getTargetNode())->getId(); + } + if (count != 0) + *os << "\""; +} + + +void IRXMLDump::writeNode (const BasicBlock* bblock) +{ + StlVector lsstore(mm); + BitSet lives(mm, irm.getOpndCount()); + +// iterate over instructions towards the top of the block + + size_t lstos = 0; + + irm.getLiveAtExit(bblock, lives); + for (const Inst* inst = (Inst*)bblock->getLastInst(); inst != 0; inst = inst->getPrevInst()) + { + if (lstos >= lsstore.size()) + { + lsstore.resize(lstos+1); + lsstore[lstos] = new (mm) BitSet(mm, lives); + } + else + *lsstore[lstos] = lives; + + lstos++; + + irm.updateLiveness(inst, lives); + } + +// iterate from top towards bottom + + for (const Inst* inst = (Inst*)bblock->getFirstInst(); inst != 0; inst = inst->getNextInst()) + { + const char* s; + *os << "getId(); + if ((s = EncoderBase::getMnemonicString(inst->getMnemonic())) != 0) + *os << "\" mnemonic=\"" << s; + *os << "\">"; + + assert(lstos != 0); + --lstos; + + BitSet* curr = lsstore[lstos]; + + const uint32 props = inst->getProperties(); + + Inst::Opnds opnds(inst, Inst::OpndRole_All); + for (Inst::Opnds::iterator it = opnds.begin(); it != opnds.end(); it = opnds.next(it)) + { + const Opnd* opnd = opnds.getOpnd(it); + + *os << " getFirstId() + << "\" role=\""; + + const uint32 roles = inst->getOpndRoles(it); + + if ((props & Inst::Properties_Conditional) != 0) + *os << "C"; + + if ((roles & Inst::OpndRole_Def) != 0) + *os << "D"; + + if ((roles & Inst::OpndRole_Use) != 0) + *os << "U"; + + *os << "\"/>"; + + curr->setBit(opnd->getId(), false); + } + + if (!curr->isEmpty()) + { + BitSet::IterB ls(*curr); + for (int i = ls.getNext(); i != -1; i = ls.getNext()) + { + const Opnd* opnd = irm.getOpnd(i); + *os << " getFirstId() + << "\" role=\"X\"/>"; + } + } + + *os << " " << endl; + } + + assert(lstos == 0); +} + + +} //namespace Ia32 +} //namespace Jitrino Index: jitrino/src/codegenerator/ia32/Ia32IRXMLDump.h =================================================================== --- jitrino/src/codegenerator/ia32/Ia32IRXMLDump.h (revision 0) +++ jitrino/src/codegenerator/ia32/Ia32IRXMLDump.h (revision 0) @@ -0,0 +1,48 @@ +/** + * @author Sergey L. Ivashin + * @version $Revision$ + */ + +#if !defined(__IA32IRXMLDump_H_INCLUDED__) +#define __IA32IRXMLDump_H_INCLUDED__ + +#include "Ia32IRManager.h" +#include "Stl.h" +#include + + + +namespace Jitrino +{ +namespace Ia32 +{ + + +class IRXMLDump +{ + +public: + + IRXMLDump (const IRManager&, std::ostream*); + ~IRXMLDump (); + + void write (); + void split (const Opnd* parent, const Opnd* child); + +protected: + + void writeOpnds (); + void writeCFG (); + void writeEdges (bool, const Node*); + void writeNode (const BasicBlock*); + + const IRManager& irm; + std::ostream* os; + MemoryManager mm; + StlVector splits; +}; + +} +} + +#endif //#if !defined(__IA32IRXMLDump_H_INCLUDED__) Index: jitrino/src/codegenerator/ia32/Ia32SpillGenDbg.h =================================================================== --- jitrino/src/codegenerator/ia32/Ia32SpillGenDbg.h (revision 0) +++ jitrino/src/codegenerator/ia32/Ia32SpillGenDbg.h (revision 0) @@ -0,0 +1,11 @@ + +#include "Ia32IRXMLDump.h" +#include "Ia32Printer.h" +#include +#include +#include + + +using ::std::endl; +using ::std::ostream; + Index: jitrino/src/codegenerator/ia32/Ia32SpillGenDbgHead.h =================================================================== --- jitrino/src/codegenerator/ia32/Ia32SpillGenDbgHead.h (revision 0) +++ jitrino/src/codegenerator/ia32/Ia32SpillGenDbgHead.h (revision 0) @@ -0,0 +1,113 @@ + + +//namespace Jitrino +//{ +//namespace Ia32 +//{ + + +void onConstruct (const SpillGen&); +void onDestruct (const SpillGen&); + + +struct Sep +{ + Sep () :first(true) {} + + bool first; +}; + +static ostream& operator << (ostream&, Sep&); + +static ostream& operator << (ostream&, const Inst&); + +static ostream& operator << (ostream&, const Opnd&); + +//static ostream& operator << (ostream&, const SpillGen::Instx&); + +static ostream& operator << (ostream&, Constraint); + +static ostream& operator << (ostream&, const SpillGen::Registers&); + +struct RegMasks +{ + RegMasks (Constraint x, SpillGen::RegMask mk) : c(x) {c.setMask(mk);} + + Constraint c; +}; + +static ostream& operator << (ostream&, RegMasks); + +static ostream& outRegMasks (ostream&, SpillGen::RegMask*, const SpillGen::Registers&); + +static ostream& operator << (ostream&, SpillGen::Opline&); + +static ostream& outInstxs (ostream&, SpillGen&); + +static ostream& operator << (ostream&, MethodDesc&); + + +//struct Dbgout : public ::std::ofstream +//{ +// Dbgout (const char* s) {open(s);} +// ~Dbgout () {close();} +//}; + + +class Histo +{ +public: + + Histo (int); + ~Histo (); + + int size () const {return lgth;} + int at (int n) const {assert(0 <= n && n < lgth); return histo[n];} + void incr (int); + void add (const Histo&); + void clear (); + +protected: + + int lgth; + int* histo; +}; + + +struct HistoCounter : public CounterBase +{ + HistoCounter () : CounterBase("HistoCounter") {} + + /*virtual*/ void write (CountWriter&); + +}; + + +//======================================================================================== +// statics +//======================================================================================== + + +static bool sos = false; + +static Histo assigns(16), + opruns(16); + +static HistoCounter histocount; + +//static Dbgout dbgout("SpillGen.txt"); + +static IRXMLDump * dbgraw = 0; + + +//======================================================================================== +// macros +//======================================================================================== + + +#define DBGOUT(s) log(LogStream::DBG).out() << s + + +//} //namespace Ia32 +//} //namespace Jitrino + Index: jitrino/src/codegenerator/ia32/Ia32SpillGenDbgTail.h =================================================================== --- jitrino/src/codegenerator/ia32/Ia32SpillGenDbgTail.h (revision 0) +++ jitrino/src/codegenerator/ia32/Ia32SpillGenDbgTail.h (revision 0) @@ -0,0 +1,298 @@ + + +//namespace Jitrino +//{ +//namespace Ia32 +//{ + + +//======================================================================================== +// Constructor & Desctructor +//======================================================================================== + + +void onConstruct (const SpillGen& spillgen) +{ + spillgen.log(LogStream::DBG).out() + << endl << "Constructed " << spillgen.getIRManager().getMethodDesc() << endl; + + if (spillgen.isLogEnabled("irxml")) + { + dbgraw = new IRXMLDump(spillgen.getIRManager(), &spillgen.log("irxml").out()); + } + +// sos = strcmp(methodTypeName, "java/util/GregorianCalendar") == 0 && +// strcmp(methodName, "computeYearAndDay") == 0 && +// strcmp(md.getSignatureString(), "(JJ)I") == 0; +} + + +void onDestruct (const SpillGen& spillgen) +{ + if (dbgraw != 0) + { + spillgen.getIRManager().fixLivenessInfo(); + dbgraw->write(); + delete dbgraw; + dbgraw = 0; + } + + spillgen.log(LogStream::DBG) << endl << "Destructed" << endl; +} + + +//======================================================================================== +// Output formatters +//======================================================================================== + + +static ostream& operator << (ostream& os, Sep& x) +{ + if (x.first) + x.first = false; + else + os << ","; + return os; +} + +static ostream& operator << (ostream& os, const Inst& x) +{ + return os << "I#" << x.getId(); +} + + +static ostream& operator << (ostream& os, const Opnd& x) +{ + os << "O#" << x.getFirstId(); + RegName rn = x.getRegName(); + if (rn != RegName_Null) + os << "<" << getRegNameString(rn) << ">"; + if (x.isPlacedIn(OpndKind_Memory)) + os << ""; + return os; +} + + +/* static ostream& operator << (ostream& os, const SpillGen::Instx& x) +{ + os << "Ix#" << x.inst->getId(); + + Sep s; + os << " {"; + + Inst::Opnds opnds(x.inst, Inst::OpndRole_All); + for (Inst::Opnds::iterator it = opnds.begin(); it != opnds.end(); it = opnds.next(it)) + { + os << s << opnds.getOpnd(it); + + OpRole oprole = x.oproles[it]; // VSH: is it supposed to cover mem sub opnds? if not then use inst->getInstLevelIndex(it); + if ((oprole & RoleDef) != 0) + os << ":Def"; + if ((oprole & RoleUse) != 0) + os << ":Use"; + if ((oprole & RoleCond) != 0) + os << ":Cond"; + if ((oprole & RoleEnd) != 0) + os << ":End"; + } + + os << "}"; + + return os; +} */ + + +/*** +std::ostream& operator << (std::ostream& os, Constraint& c) +{ + return os << "{kind=" << c.kind << " size=" << c.size << " mask=" << c.mask << "}"; +} +***/ + +static ostream& operator << (ostream& os, Constraint c) +{ + IRPrinter::printConstraint(os, c); + return os; +} + + +static ostream& operator << (ostream& os, const SpillGen::Registers& x) +{ + Sep s;; + os << "{"; + for (SpillGen::Registers::const_iterator it = x.begin(); it != x.end(); ++it) + os << s << *it; + return os << "}"; +} + + +static ostream& operator << (ostream& os, RegMasks x) +{ + return os << x.c; +} + + +static ostream& outRegMasks (ostream& os, SpillGen::RegMask* x, const SpillGen::Registers& registers) +{ + Sep s;; + os << "{"; + for (size_t rk = 0; rk != registers.size(); ++rk) + { + SpillGen::RegMask msk = x[rk]; + + for (size_t rx = 0; msk != 0; ++rx, msk >>= 1) + if ((msk & 1) != 0) + { + RegName reg = getRegName((OpndKind)registers[rk].getKind(), registers[rk].getSize(), rx); + os<< s << getRegNameString(reg); + } + } + return os << "}"; +} + + +static ostream& outInstxs (ostream& os, SpillGen& spillgen) +{ + os << "Instxs" << endl; + for (SpillGen::Instxs::iterator instxp = spillgen.instxs.begin(); instxp != spillgen.instxs.end(); ++instxp) + { + if (instxp == spillgen.instxs.begin()) + { + os << " [prefix]" << endl; + } + else + { + os << " I#" << instxp->inst->getId() << " operands"; + SpillGen::OpRole* oproles = instxp->oproles; + for (size_t n = 0; n != instxp->nbopnds; ++n, ++oproles) + { + os << " " << n; + if ((*oproles & SpillGen::RoleDef)) + os << ":Def"; + if ((*oproles & SpillGen::RoleUse)) + os << ":Use"; + if ((*oproles & SpillGen::RoleCond)) + os << ":Cond"; + if ((*oproles & SpillGen::RoleEnd)) + os << ":End"; + } + os << endl; + } + + os << " regusage"; outRegMasks(os, instxp->regusage, spillgen.registers); + os << endl; + } + return os; +} + + +static ostream& operator << (ostream& os, SpillGen::Opline& opline) +{ + os << endl << "Opline " << *opline.opnd; + + Sep s; + os << " {"; + for (SpillGen::Opline::Ops::reverse_iterator it = opline.ops->rbegin(); it != opline.ops->rend(); ++it) + { + const SpillGen::Op& op = *it; + os << s << *op.instx->inst; + if ((op.oprole & SpillGen::RoleDef) != 0) + os << ":Def"; + if ((op.oprole & SpillGen::RoleUse) != 0) + os << ":Use"; + if ((op.oprole & SpillGen::RoleCond) != 0) + os << ":Cond"; + if ((op.oprole & SpillGen::RoleEnd) != 0) + os << ":End"; + } + os << "}"; + + if (opline.at_start) + os << " live_at_start"; + if (opline.at_exit) + os << " live_at_exit"; + if (opline.catched) + os << " catched"; + os << endl; + + //os << "ConstraintKind_Initial " << opline.opnd->getConstraint(Opnd::ConstraintKind_Initial) << endl; + //os << "ConstraintKind_Calculated " << opline.opnd->getConstraint(Opnd::ConstraintKind_Calculated) << endl; + + return os; +} + + +static ostream& operator << (ostream& os, MethodDesc& md) +{ + return os << md.getParentType()->getName() << "." << md.getName() << md.getSignatureString(); +} + + +//======================================================================================== +// class Histo +//======================================================================================== + + +Histo::Histo (int n) +{ + assert(n > 0); + histo = new int [lgth = n]; + clear(); +} + + +Histo::~Histo () +{ + delete [] histo; +} + + +void Histo::incr (int n) +{ + assert(n >= 0); + ++histo[n < lgth ? n : lgth-1]; +} + + +void Histo::add (const Histo& other) +{ + for (int n = 0; n < other.lgth; ++n) + histo[n < lgth ? n : lgth-1] += other.histo[n]; +} + + +void Histo::clear () +{ + for (int n = 0; n < lgth; ++n) + histo[n] = 0; +} + + +//======================================================================================== +// class HistoCounter +//======================================================================================== + + +void HistoCounter::write (CountWriter& cw) +{ + std::ostringstream sbuff; + + for (int i = 0, n = opruns.size(); i < n; ++i) + { + sbuff.seekp(0); + sbuff << "ia32:spillgen:opruns." << i; + cw.write(sbuff.str().c_str(), opruns.at(i)); + } + + for (int i = 0, n = assigns.size(); i < n; ++i) + { + sbuff.seekp(0); + sbuff << "ia32:spillgen:assigns." << i; + cw.write(sbuff.str().c_str(), opruns.at(i)); + } +} + + +//} //namespace Ia32 +//} //namespace Jitrino +