You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/05/16 13:58:36 UTC

svn commit: r538551 [2/2] - in /harmony/enhanced/drlvm/trunk/vm/jitrino: config/em64t/ config/ia32/ src/codegenerator/ia32/

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32WebMaker.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32WebMaker.cpp?view=diff&rev=538551&r1=538550&r2=538551
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32WebMaker.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32WebMaker.cpp Wed May 16 04:58:35 2007
@@ -20,18 +20,18 @@
  */
 
 #include "Ia32IRManager.h"
+#include "Ia32ConstraintsResolver.h"
 #include "XTimer.h"
 #include "Counter.h"
 #include "Stl.h"
 
-#ifdef _DEBUG__WEBMAKER
+#ifdef _DEBUG_WEBMAKER
 #include <iostream>
 #include <iomanip>
-#include "Ia32IRXMLDump.h"
 #ifdef _MSC_VER
 #pragma warning(disable : 4505)   //unreferenced local function has been removed
 #endif //#ifdef _MSC_VER
-#endif //#ifdef _DEBUG__WEBMAKER
+#endif //#ifdef _DEBUG_WEBMAKER
 
 
 using namespace std;
@@ -51,7 +51,7 @@
     {
         int globid;         // -1 for local definition or uniquue id (starting from 0)
         Inst* defp;         // defining instruction
-        size_t linkx;
+        unsigned linkx;
         bool visited;
 
         typedef StlVector<Inst*> Instps;
@@ -79,10 +79,10 @@
 
     struct Nodex
     {
-        Nodex (MemoryManager& mm, size_t s) :globentrys(mm,(uint32)s), 
-                                             globdefsp (0), 
-                                             globkillsp(0),
-                                             globexitsp(0) {}
+        Nodex (MemoryManager& mm, unsigned s) :globentrys(mm, s), 
+                                               globdefsp (0), 
+                                               globkillsp(0),
+                                               globexitsp(0) {}
 
         BitSet globentrys;  // all global definitions available at the block entry
         BitSet* globdefsp,  // can be 0
@@ -93,10 +93,10 @@
     typedef StlVector <Nodex*> Nodexs;
     Nodexs nodexs;
 
-    /*const*/ size_t opandcount;
-    /*const*/ size_t nodecount;
-    size_t splitcount;
-    size_t globcount;
+    /*const*/ unsigned opandcount;
+    /*const*/ unsigned nodecount;
+    unsigned splitcount;
+    unsigned globcount;
 
 
     WebMaker ()                     :mm(1000, "WebMaker"), opndxs(mm), nodexs(mm) {}
@@ -105,6 +105,7 @@
     uint32 getSideEffects () const  {return splitcount == 0 ? 0 : SideEffect_InvalidatesLivenessInfo;}
 
     void runImpl();
+    void calculateConstraints();
 
     void phase1();
     void phase2();
@@ -118,7 +119,7 @@
 
 static ActionFactory<WebMaker> _webmaker("webmaker");
 
-static Counter<size_t> count_splitted("ia32:webmaker:splitted", 0);
+static Counter<int> count_splitted("ia32:webmaker:splitted", 0);
 
 
 //========================================================================================
@@ -126,13 +127,10 @@
 //========================================================================================
 
 
-#ifdef _DEBUG__WEBMAKER
-
 using std::endl;
 using std::ostream;
 
-static void onConstruct (const IRManager&);
-static void onDestruct  ();
+#ifdef _DEBUG_WEBMAKER
 
 struct Sep
 {
@@ -149,22 +147,160 @@
 
 static ostream& operator << (ostream&, /*const*/ BitSet*);
 
-struct Dbgout : public  ::std::ofstream
+#define DBGOUT(s) log(LogStream::DBG).out() << s
+
+#else
+
+#define DBGOUT(s) 
+
+#endif
+
+
+//========================================================================================
+//  Inst::Opnds
+//========================================================================================
+
+class InstOpnds
 {
-    Dbgout (const char* s)          {open(s);}
-    ~Dbgout ()                      {close();}
+public:
+
+    InstOpnds (const Inst* inst, uint32 roles = Inst::OpndRole_All, bool forw = true);
+
+    bool hasMore () const           {return opnd != 0;}
+    void next ()                    {move();}
+    Opnd*  getOpnd () const         {return opnd;}
+    uint32 getRole () const         {return role;}
+
+protected:
+
+    bool move ();
+
+    const Inst*  inst;
+    const uint32 roles;
+    const unsigned main_count;
+
+    unsigned state,
+             main_idx,
+              sub_idx;
+
+    uint32 role;
+    Opnd* opnd;
+    Opnd* main_opnd;
 };
 
-static Dbgout dbgout("WebMaker.txt");
 
-#define DBGOUT(s) dbgout << s
-//#define DBGOUT(s) std::cerr << s
+InstOpnds::InstOpnds (const Inst* i, uint32 r, bool forw)
+:inst(i), roles(r), main_count(i->getOpndCount())
+{
+    if (main_count == 0)
+    {
+        state = 6;
+        opnd = 0;
+    }
+    else if (forw)
+    {
+        main_idx = 0;
+        state = 0;
+        move();
+    }
+    else
+    {
+        main_idx = main_count;
+        state = 3;
+        move();
+    }
+}
 
-#else
 
-#define DBGOUT(s) 
+bool InstOpnds::move ()
+{
+    opnd = 0;
 
-#endif
+    do
+        switch (state)
+        {
+        //  forward iteration
+
+            case 0:     // main operands
+                opnd = inst->getOpnd(main_idx);
+                role = inst->getOpndRoles(main_idx);
+                if (++main_idx == main_count)
+                {
+                    main_idx = 0;
+                    state = 1;
+                }
+                return true;
+
+            case 1:     // find next memory operand
+                for (;; ++main_idx)
+                {
+                    if (main_idx == main_count)
+                    {
+                        state = 6;
+                        return false;
+                    }
+
+                    main_opnd = inst->getOpnd(main_idx);
+                    if (main_opnd->getMemOpndKind() != MemOpndKind_Null)
+                        break;
+                }
+
+                sub_idx = 0;
+                state = 2;
+                // fall to case 2
+
+            case 2:     // sub operands
+                opnd = main_opnd->getMemOpndSubOpnd((MemOpndSubOpndKind)sub_idx);
+                role = Inst::OpndRole_OpndLevel | Inst::OpndRole_Use;
+                if (++sub_idx == 4)
+                {
+                    ++main_idx;
+                    state = 1;
+                }
+                break;
+
+        //  backward iteration
+
+            case 3:     // find prev memory operand
+                for (;;)
+                {
+                    if (main_idx == 0)
+                    {
+                        main_idx = main_count;
+                        state = 5;
+                        goto S5;
+                    }
+
+                    main_opnd = inst->getOpnd(--main_idx);
+                    if (main_opnd->getMemOpndKind() != MemOpndKind_Null)
+                        break;
+                }
+
+                sub_idx = 4;
+                state = 4;
+                // fall to case 4
+
+            case 4:     // sub operands
+                opnd = main_opnd->getMemOpndSubOpnd((MemOpndSubOpndKind)--sub_idx);
+                role = Inst::OpndRole_OpndLevel | Inst::OpndRole_Use;
+                if (sub_idx == 0)
+                    state = 3;
+                break;
+
+            case 5:     // main operands
+S5:             opnd = inst->getOpnd(--main_idx);
+                role = inst->getOpndRoles(main_idx);
+                if (main_idx == 0)
+                    state = 6;
+                return true;
+
+            case 6:
+                return false;
+        }
+    while (opnd == 0 /*TBD: check roles here */);
+
+    return true;
+}
 
 
 //========================================================================================
@@ -174,10 +310,6 @@
 
 void WebMaker::runImpl()
 {
-#ifdef _DEBUG__WEBMAKER
-    onConstruct(irm);
-#endif
-
     opandcount = irManager->getOpndCount();
     nodecount = irManager->getFlowGraph()->getMaxNodeId();
 
@@ -192,36 +324,43 @@
         phase2();
         phase3();
         phase4();
+
+        if (splitcount != 0 && getBoolArg("calc", false))
+            calculateConstraints();
     }
 
     count_splitted += splitcount;
-    DBGOUT("***splitcount=" << splitcount << "/" << count_splitted << endl;)
+    DBGOUT("splitcount=" << splitcount << "/" << count_splitted << endl;)
+}
 
-#ifdef _DEBUG__WEBMAKER
-    onDestruct();
-#endif
+
+void WebMaker::calculateConstraints ()
+{
+    DBGOUT("Calculating constraints" << endl;)
+
+    irManager->calculateLivenessInfo();
+    ConstraintsResolverImpl impl(*irManager, true);
+    impl.run();
 }
 
 
 void WebMaker::phase1()
 {
-    static CountTime phase1Timer("timer:ia32::webmaker:phase1");
-    AutoTimer tm(phase1Timer);
-
     opndxs.resize(opandcount);
-    for (size_t i = 0; i != opandcount; ++i)
+    for (unsigned i = 0; i != opandcount; ++i)
     {
         Opndx* opndxp = 0;
-        if (!irManager->getOpnd((uint32)i)->hasAssignedPhysicalLocation())
+        if (!irManager->getOpnd(i)->hasAssignedPhysicalLocation())
             opndxp = new Opndx(mm);
         opndxs[i] = opndxp;
     }
 
-    BitSet lives(mm, (uint32)opandcount);
+    BitSet lives(mm, opandcount);
     globcount = 0;
 
     const Nodes& postOrder = irManager->getFlowGraph()->getNodesPostOrder();
-    for (Nodes::const_iterator it = postOrder.begin(), end = postOrder.end(); it!=end; ++it) {
+    for (Nodes::const_iterator it = postOrder.begin(), end = postOrder.end(); it!=end; ++it) 
+    {
         Node* nodep = *it;
         
         if (nodep->isBlockNode())
@@ -229,14 +368,17 @@
             for (Inst* instp = (Inst*)nodep->getFirstInst(); instp!=NULL; instp = instp->getNextInst()) {
                 const uint32 iprops = instp->getProperties();
                 Inst::Opnds defs(instp, Inst::OpndRole_AllDefs);
-                size_t itx = 0;
+                unsigned itx = 0;
                 for (Inst::Opnds::iterator it = defs.begin(); it != defs.end(); it = defs.next(it), ++itx)
+                //for (InstOpnds inops(instp, Inst::OpndRole_All, true); inops.hasMore(); inops.next())
                 {
                     Opnd* opndp = instp->getOpnd(it);
+                    //Opnd* opndp = inops.getOpnd();
                     Opndx* opndxp = opndxs.at(opndp->getId());
                     if (opndxp != 0)
                     {
-                        const uint32 oprole = const_cast<const Inst*>(instp)->getOpndRoles((uint32)itx);
+                        const uint32 oprole = const_cast<const Inst*>(instp)->getOpndRoles(itx);
+                        //const uint32 oprole = inops.getRole();
                         const bool isdef = ((oprole & Inst::OpndRole_UseDef) == Inst::OpndRole_Def)
                                         && ((iprops & Inst::Properties_Conditional) == 0 );
                         if (isdef)
@@ -253,6 +395,8 @@
                 }
             }
 
+        //  Mark all global definitions
+
             irManager->getLiveAtExit(nodep, lives);
             BitSet::IterB bsk(lives);
             for (int i = bsk.getNext(); i != -1; i = bsk.getNext())
@@ -272,7 +416,7 @@
         }
     }
 
-#ifdef _DEBUG__WEBMAKER
+#ifdef _DEBUG_WEBMAKER
 /*
     dbgout << "--- phase1 ---" << endl;
     for (size_t i = 0; i != opandcount; ++i)
@@ -295,9 +439,6 @@
 
 void WebMaker::phase2()
 {
-    static CountTime phase2Timer("timer:ia32::webmaker:phase2");
-    AutoTimer tm(phase2Timer);
-
     nodexs.resize(nodecount);
     for (size_t n = 0; n != nodecount; ++n)
         nodexs[n] = new Nodex(mm, globcount);
@@ -324,8 +465,6 @@
             opndxp->cbbp = 0;
             opndxp->copdefp = 0;
         }
-
-    
     
     BitSet wrkbs(mm, (uint32)globcount);
     bool   wrkbsvalid;
@@ -391,7 +530,7 @@
         }
     }
 
-#ifdef _DEBUG__WEBMAKER
+#ifdef _DEBUG_WEBMAKER
 /*
     dbgout << "--- total passes:" << passnb << endl;
     for (size_t n = 0; n != nodecount; ++n)
@@ -409,50 +548,42 @@
 
 void WebMaker::phase3()
 {
-    static CountTime phase3Timer("timer:ia32::webmaker:phase3");
-    AutoTimer tm(phase3Timer);
-
-    DBGOUT("--- phase3 ---" << endl;)
-
     const Nodes& postOrder  = irManager->getFlowGraph()->getNodesPostOrder();
-    for (Nodes::const_iterator it = postOrder.begin(), end = postOrder.end(); it!=end; ++it) {
+    for (Nodes::const_iterator it = postOrder.begin(), end = postOrder.end(); it!=end; ++it) 
+    {
         Node* nodep = *it;
         if (nodep->isBlockNode())
         {
             const BitSet*  globentryp = &nodexs.at(nodep->getId())->globentrys;
             
-            for (Inst* instp = (Inst*)nodep->getFirstInst(); instp!=NULL; instp = instp->getNextInst()) {
+            for (Inst* instp = (Inst*)nodep->getFirstInst(); instp != 0; instp = instp->getNextInst()) 
             {
                 const uint32 iprops = instp->getProperties();
-                Inst::Opnds all(instp, Inst::OpndRole_All);
-                size_t itx = 0;
-                for (Inst::Opnds::iterator it = all.begin(); it != all.end(); it = all.next(it), ++itx)
+
+                for (InstOpnds inops(instp, Inst::OpndRole_All, false); inops.hasMore(); inops.next())
                 {
-                    Opnd* opndp = instp->getOpnd(it);
+                    Opnd* opndp = inops.getOpnd();
                     Opndx* opndxp = opndxs.at(opndp->getId());
                     if (opndxp != 0)
                     {
                         OpDef* opdefp = 0;
-                        const uint32 oprole = const_cast<const Inst*>(instp)->getOpndRoles((uint32)itx);
+                        const uint32 oprole = inops.getRole();
                         const bool isdef = ((oprole & Inst::OpndRole_UseDef) == Inst::OpndRole_Def)
                                         && ((iprops & Inst::Properties_Conditional) == 0 );
-                        DBGOUT(" O#" << opndp->getFirstId() << "(#" << opndp->getId() << ") def:" << isdef;)
                         DBGOUT(" B#" << instp->getBasicBlock()->getId() << " " << *instp;)
+                        DBGOUT(" " << *opndp << (isdef ? " DEF" : "") << endl;)
 
                         if (isdef) 
                         {// opand definition here
                             Opndx::OpDefs::iterator it = opndxp->opdefs.begin(),
                                                     end = opndxp->opdefs.end();
-                            //if (opndxp->copdefp != 0)
-                            //  it = opndxp->copdefp;
                             for (; it != end && it->defp != instp; ++it)
                                 ;
 
                             assert(it != end);
                             opdefp = &*it;
-                            opndxp->copdefp = opdefp;
+                            opndxp->copdefp = opdefp;   
                             opndxp->cbbp = nodep;
-                            DBGOUT(" found1 globid#" << opdefp->globid << " def B#" << opdefp->defp->getBasicBlock()->getId() << " " << *opdefp->defp << endl;)
                         }
                         else
                         {// opand usage here
@@ -473,68 +604,59 @@
                                         lastdefp = opdefp;
                                     }
                                 assert(lastdefp != 0);
-                                DBGOUT(" found2 globid#" << opdefp->globid << " def B#" << opdefp->defp->getBasicBlock()->getId() << " " << *opdefp->defp << endl;)
                             }
                             else
                             {// it can be usage of global or local definition
                                 opdefp = opndxp->copdefp;
-                                DBGOUT(" found3 globid#" << opdefp->globid << " def B#" << opdefp->defp->getBasicBlock()->getId() << " " << *opdefp->defp << endl;)
                             }
                         }
                         assert(opdefp != 0);
 
                         if (opdefp->globid == -1)
-                        {
+                        {// local operand
                             if (isdef)
                             {
                                 ++opndxp->webscount;
                                 if (opndxp->webscount > 1)
                                 {
                                     opndxp->newopndp = splitOpnd(opndp);
-                                    DBGOUT("**new local web found O#" << opndxp->newopndp->getFirstId() << "(#" << opndxp->newopndp->getId() << ")" << endl;)
+                                    DBGOUT("**new local web found " << *opndp << " -> " << *opndxp->newopndp << endl;)
                                 }
                             }
 
                             if (opndxp->webscount > 1 && opdefp->defp->getNode() == nodep)
                             {
-                                instp->replaceOpnd(opndp, opndxp->newopndp);
-                                DBGOUT("  opand replaced by O#" << opndxp->newopndp->getFirstId() << "(#" << opndxp->newopndp->getId() << ")" << endl;)
+                                instp->replaceOpnd(opndp, opndxp->newopndp, isdef ? Inst::OpndRole_AllDefs : Inst::OpndRole_AllUses);
+                                DBGOUT(" replace B#" << instp->getBasicBlock()->getId() << " " << *instp << endl;)
                             }
                         }
                         else
-                        {
+                        {// global oprand
                             if (opdefp->useps == 0)
                                 opdefp->useps = new OpDef::Instps(mm);
-                            opdefp->useps->push_back(instp);
+                            if (!isdef)
+                                opdefp->useps->push_back(instp);
                         }
                     }
                 }
             }
         }
-        }
     }
 }
 
 
 void WebMaker::phase4()
 {
-    static CountTime phase4Timer("timer:ia32::webmaker:phase4");
-    AutoTimer tm(phase4Timer);
-
-    DBGOUT("--- phase4 ---" << endl;)
-
     Opndx* opndxp;
-    for (size_t i = 0; i != opandcount; ++i)
+    for (unsigned i = 0; i != opandcount; ++i)
         if ((opndxp = opndxs[i]) != 0  && !opndxp->opdefs.empty())
         {
-            Opnd* opndp = irManager->getOpnd((uint32)i);
+            Opnd* opndp = irManager->getOpnd(i);
             Opndx::OpDefs& opdefs = opndxp->opdefs;
-            DBGOUT(" O#" << opndp->getFirstId() << "(#" << i << ")" << endl;)
 
-            for (size_t itx = 0; itx != opdefs.size(); ++itx)
+            for (unsigned itx = 0; itx != opdefs.size(); ++itx)
             {
                 OpDef* opdefp = &opdefs[itx];
-                DBGOUT("  " <<  itx << "->" << opdefp->linkx << " globid#" << opdefp->globid << endl;)
                 if (opdefp->globid != -1 && !opdefp->visited)
                 {
                     Opnd* newopndp = 0;
@@ -542,22 +664,23 @@
                     if (opndxp->webscount > 1)
                     {
                         newopndp = splitOpnd(opndp);
-                        DBGOUT("**new global web found O#" << newopndp->getFirstId() << "(#" << newopndp->getId() << ")" << endl;)
+                        DBGOUT("**new global web found " << *opndp << " -> " << *newopndp<< endl;)
                     }
 
                     while (!opdefp->visited)
                     {
-                        DBGOUT("   -visited globid#" << opdefp->globid << endl;)
-
-                        if (newopndp != 0 && opdefp->useps != 0)
+                        if (newopndp != 0)
                         {
+                            DBGOUT(" defp " << *opdefp->defp << endl;)
+                            opdefp->defp->replaceOpnd(opndp, newopndp, Inst::OpndRole_AllDefs);
+                            DBGOUT(" replace B#" << opdefp->defp->getBasicBlock()->getId() << " " << *opdefp->defp << endl;)
+
                             OpDef::Instps::iterator it = opdefp->useps->begin(),
-                                                   end = opdefp->useps->end();
+                                                    end = opdefp->useps->end();
                             for (; it != end; ++it)
                             {
-                                (*it)->replaceOpnd(opndp, newopndp);
-                                DBGOUT(" replace B#" << (*it)->getBasicBlock()->getId() << " " << *(*it);)
-                                DBGOUT(" O#" << opndp->getFirstId() << "(#" << opndp->getId() << ")" << endl;)
+                                (*it)->replaceOpnd(opndp, newopndp, Inst::OpndRole_AllUses);
+                                DBGOUT(" replace B#" << (*it)->getBasicBlock()->getId() << " " << **it << endl;)
                             }
                         }
 
@@ -581,19 +704,18 @@
             break;
     }
 
-    size_t wx = lastdefp->linkx;
+    unsigned wx = lastdefp->linkx;
     lastdefp->linkx = opdefp->linkx;
     opdefp->linkx = wx;
-    DBGOUT("** glob def linked " << opdefp->globid << " + " << lastdefp->globid << endl;)
 }
 
 
 BitSet* WebMaker::bitsetp (BitSet*& bsp)
 {
     if (bsp == 0)
-        bsp = new BitSet(mm, (uint32)globcount);
+        bsp = new BitSet(mm, globcount);
     else
-        bsp->resize((uint32)globcount);
+        bsp->resize(globcount);
     return bsp;
 }
 
@@ -601,46 +723,17 @@
 Opnd* WebMaker::splitOpnd (const Opnd* op)
 {
     Opnd* np = irManager->newOpnd(op->getType(), op->getConstraint(Opnd::ConstraintKind_Initial));
-    np->setCalculatedConstraint( op->getConstraint(Opnd::ConstraintKind_Calculated)); 
     ++splitcount;
     return np;
 }
 
 
 //========================================================================================
-// Internal debug helpers
-//========================================================================================
-
-
-#ifdef _DEBUG__WEBMAKER
-
-static void onConstruct (const IRManager& irm)
-{
-    MethodDesc& md = irm.getMethodDesc();
-    const char * methodName = md.getName();
-    const char * methodTypeName = md.getParentType()->getName();
-    DBGOUT(endl << "Constructed " << methodTypeName  << "." << methodName 
-           << "(" << md.getSignatureString() << ")" << endl;)
-
-//  sos = strcmp(methodTypeName, "spec/benchmarks/_213_javac/BatchEnvironment") == 0 &&
-//        strcmp(methodName,     "flushErrors") == 0;
-}
-
-
-static void onDestruct ()
-{
-    DBGOUT(endl << "Destructed" << endl;)
-}
-
-#endif //#ifdef _DEBUG__WEBMAKER
-
-
-//========================================================================================
 //  Output formatters
 //========================================================================================
 
 
-#ifdef _DEBUG__WEBMAKER
+#ifdef _DEBUG_WEBMAKER
 
 static ostream& operator << (ostream& os, Sep& x)
 {
@@ -686,7 +779,7 @@
     return os;
 }
 
-#endif //#ifdef _DEBUG__WEBMAKER
+#endif //#ifdef _DEBUG_WEBMAKER
 
 } //namespace Ia32
 } //namespace Jitrino