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/04/11 14:28:48 UTC

svn commit: r527470 [1/2] - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf: ./ include/

Author: varlax
Date: Wed Apr 11 05:28:45 2007
New Revision: 527470

URL: http://svn.apache.org/viewvc?view=rev&rev=527470
Log:
Applied HARMONY-3596 [drlvm][ia64][jit] Guarded code liveness analysis implemented

Added:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfInstrumentator.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfLiveManager.h   (with props)
Removed:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfDce.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfDce.h
Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeGenerator.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfLiveAnalyzer.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfRegisterAllocator.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeSupport.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp Wed Apr 11 05:28:45 2007
@@ -216,7 +216,6 @@
 Cfg::Cfg(MemoryManager &mm, CompilationInterface &compilationInterface):
     mm(mm),
     compilationInterface(compilationInterface),
-    maxNodeId(0),
     enterNode(NULL),
     exitNode(NULL),
     searchResult(mm),
@@ -229,13 +228,13 @@
 
 NodeVector& Cfg::search(SearchKind searchKind) { 
 
-    if(lastSearchKind == searchKind) return searchResult;
+    if (lastSearchKind == searchKind) return searchResult;
     lastSearchKind = searchKind;
 
     NodeSet visitedNodes(mm);
     searchResult.clear();
 
-    switch(searchKind) {
+    switch (searchKind) {
         case SEARCH_DIRECT_ORDER : makeDirectOrdered(exitNode, visitedNodes); break;
         case SEARCH_POST_ORDER   : makePostOrdered(enterNode, visitedNodes);  break;
         case SEARCH_LAYOUT_ORDER : makeLayoutOrdered();                       break;
@@ -254,12 +253,12 @@
     visitedNodes.insert(node);                       // mark node visited
 
     EdgeVector& inEdges = node->getInEdges();        // get inEdges
-    for(uint32 i=0; i<inEdges.size(); i++) {         // iterate through inEdges
-        Node *pred = inEdges[i]->getSource();     // get pred node
-        if(visitedNodes.count(pred) == 1) continue;  // if it is already visited - ignore
+    for (uint32 i=0; i<inEdges.size(); i++) {        // iterate through inEdges
+        Node *pred = inEdges[i]->getSource();        // get pred node
+        if (visitedNodes.count(pred) == 1) continue; // if it is already visited - ignore
         makeDirectOrdered(pred, visitedNodes);       // we have found unvisited pred - reenter
     }
-    searchResult.push_back(node);                    // all succs have been visited - place node in searchResult vector
+    searchResult.push_back(node);                    // all preds have been visited - place node in searchResult vector
 }
 
 //----------------------------------------------------------------------------------------//
@@ -270,9 +269,9 @@
     visitedNodes.insert(node);                        // mark node visited
 
     EdgeVector& outEdges = node->getOutEdges();       // get outEdges
-    for(uint32 i=0; i<outEdges.size(); i++) {         // iterate through outEdges
-        Node *succ = outEdges[i]->getTarget();     // get succ node
-        if(visitedNodes.count(succ) == 1) continue;   // if it is already visited - ignore
+    for (uint32 i=0; i<outEdges.size(); i++) {        // iterate through outEdges
+        Node *succ = outEdges[i]->getTarget();        // get succ node
+        if (visitedNodes.count(succ) == 1) continue;  // if it is already visited - ignore
         makePostOrdered(succ, visitedNodes);          // we have found unvisited succ - reenter
     }
     searchResult.push_back(node);                     // all succs have been visited - place node in searchResult vector
@@ -282,8 +281,8 @@
 
 void Cfg::makeLayoutOrdered() {
 
-    BbNode *node = (BbNode *)getEnterNode();
-    while(node != NULL) {
+    BbNode *node = getEnterNode();
+    while (node != NULL) {
         searchResult.push_back(node);
         node = node->getLayoutSucc();
     }
@@ -291,3 +290,4 @@
 
 } // IPF
 } // Jitrino
+

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp Wed Apr 11 05:28:45 2007
@@ -21,11 +21,11 @@
  */
 
 #include "Jitrino.h"
+#include "CodeSelectors.h"
 #include "IpfCodeGenerator.h"
 #include "IpfCodeSelector.h"
 #include "IpfCodeLayouter.h"
 #include "IpfLiveAnalyzer.h"
-#include "IpfDce.h"
 #include "IpfRegisterAllocator.h"
 #include "IpfSpillGen.h"
 #include "IpfIrPrinter.h"
@@ -33,8 +33,7 @@
 #include "IpfPrologEpilogGenerator.h"
 #include "IpfRuntimeSupport.h"
 #include "IpfCfgVerifier.h"
-#include "CodeSelectors.h"
-//#include "IpfInstrumentator.h"
+#include "IpfInstrumentator.h"
 
 namespace Jitrino {
 namespace IPF {
@@ -75,45 +74,30 @@
     methodDesc           = compilationInterface->getMethodToCompile();
     IrPrinter irPrinter(*cfg);
 
-    if(LOG_ON) {
-        const char *methodName     = methodDesc->getName();
-        const char *methodTypeName = (methodDesc->getParentType()!=NULL
-            ? methodDesc->getParentType()->getName()
-            : "");
-        const char * methodSignature = methodDesc->getSignatureString();
-    
-        IPF_LOG << endl << methodTypeName << "." << methodName << methodSignature << endl;
-    }
-
-    //compilationInterface->lockMethodData();
-
+    IPF_LOG << endl << IrPrinter::toString(methodDesc) << endl;
     IPF_LOG << endl << "=========== Stage: Code Selector =============================" << endl;
     IpfMethodCodeSelector ipfMethodCodeSelector(*cfg, *compilationInterface);
     methodCodeSelector->selectCode(ipfMethodCodeSelector);
 
     methodDesc = ipfMethodCodeSelector.getMethodDesc();
-    cfg->getOpndManager()->initCompBases((BbNode *)cfg->getEnterNode());
+    cfg->getOpndManager()->insertProlog(*cfg);
     cfg->getOpndManager()->saveThisArg();
-    if(LOG_ON) irPrinter.printCfgDot("/cs.dot");
+    if(LOG_ON) irPrinter.printCfgDot("cs.dot");
 
-    IPF_LOG << endl << "=========== Stage: Code Instrumentation ======================" << endl;
+//    IPF_LOG << endl << "=========== Stage: Code Instrumentation ======================" << endl;
 //    Instrumentator instrumentator(*cfg);
 //    instrumentator.instrument();
 
     IPF_LOG << endl << "=========== Stage: Code Layouter =============================" << endl;
     CodeLayouter codeLayouter(*cfg);
     codeLayouter.layout();
-    if(LOG_ON) irPrinter.printCfgDot("/cl.dot");
+    if(LOG_ON) irPrinter.printCfgDot("cl.dot");
     if(LOG_ON) irPrinter.printAsm(LOG_OUT);
 
-    IPF_LOG << endl << "=========== Stage: Liveness analyzis =========================" << endl;
+    IPF_LOG << endl << "=========== Stage: Liveness analysis =========================" << endl;
     LiveAnalyzer liveAnalyzer(*cfg);
-    liveAnalyzer.makeLiveSets(false);
-
-    IPF_LOG << endl << "=========== Stage: Dead Code Eliminator ======================" << endl;
-    Dce dce(*cfg);
-    dce.eliminate();
-    liveAnalyzer.makeLiveSets(false);
+    liveAnalyzer.analyze();
+    liveAnalyzer.dce();
 
     IPF_LOG << endl << "=========== Stage: Build GC Root Set =========================" << endl;
     RuntimeSupport runtimeSupport(*cfg, *compilationInterface);
@@ -139,8 +123,6 @@
 
     IPF_LOG << endl << "=========== Stage: Make Runtime Info =========================" << endl;
     runtimeSupport.makeRuntimeInfo();
-
-    //compilationInterface->unlockMethodData();
     
     if(ret) IPF_LOG << endl << "=========== Compilation Successful ===========================" << endl;
     else    IPF_LOG << endl << "=========== Compilation Failed ===============================" << endl;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp Wed Apr 11 05:28:45 2007
@@ -45,6 +45,7 @@
 CodeLayouter::CodeLayouter(Cfg &cfg) : 
     mm(cfg.getMM()),
     cfg(cfg),
+    opndManager(cfg.getOpndManager()),
     chains(mm),
     visitedNodes(mm) {
 }
@@ -107,7 +108,7 @@
     IPF_LOG << "    branch inst is " << IrPrinter::toString(branchInst);
     
     if (addr2node.find(addr) == addr2node.end()) {              // this call has not been moved in outstanding node
-        callNode = new(mm) BbNode(mm, cfg.getNextNodeId(), 0);  // create new node
+        callNode = new(mm) BbNode(mm, opndManager->getNextNodeId(), 0);  // create new node
         callInst = new(mm) Inst(mm, INST_BRL13, CMPLT_BTYPE_CALL, cfg.getOpndManager()->getP0());
         for (uint16 i=1; i<opnds.size(); i++) callInst->addOpnd(opnds[i]);
         callNode->addInst(callInst);                            // create and add call instruction 
@@ -399,7 +400,7 @@
 
 void CodeLayouter::setBranchTargets() {
     
-    BbNode *node = (BbNode*) cfg.getEnterNode();
+    BbNode *node = cfg.getEnterNode();
     for(; node != NULL; node = node->getLayoutSucc()) {
 
         IPF_LOG << "    node" << left << setw(3) << node->getId();
@@ -477,7 +478,7 @@
     
     // create new node for unconditional branch on through edge target node 
     // branch instruction will be inserted in fixUnconditionalBranch method
-    BbNode *branchNode = new(mm) BbNode(mm, cfg.getNextNodeId(), fallThroughNode->getExecCounter());
+    BbNode *branchNode = new(mm) BbNode(mm, opndManager->getNextNodeId(), fallThroughNode->getExecCounter());
     branchNode->setLayoutSucc(layoutSuccNode); // layout successor of current node becomes layoute successor of new node
     node->setLayoutSucc(branchNode);           // the new node becomes layout successor of current node
 
@@ -537,7 +538,7 @@
     // Add branch to through edge target
     Opnd    *p0         = cfg.getOpndManager()->getP0();
     NodeRef *targetNode = cfg.getOpndManager()->newNodeRef(target);
-    node->addInst(new(mm) Inst(mm, INST_BR, CMPLT_WH_SPTK, CMPLT_PH_MANY, p0, targetNode));
+    node->addInst(new(mm) Inst(mm, INST_BR, CMPLT_WH_SPTK, CMPLT_PH_FEW, p0, targetNode));
     
     throughEdge->setEdgeKind(EDGE_BRANCH);
     IPF_LOG << " branch on node" << target->getId() << " added" << endl;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp Wed Apr 11 05:28:45 2007
@@ -120,7 +120,8 @@
     cfg(cfg),
     nodes(nodes), 
     opnds(opnds),
-    compilationInterface(compilationInterface) {
+    compilationInterface(compilationInterface),
+    opndManager(cfg.getOpndManager()) {
 }
 
 //----------------------------------------------------------------------------------------//
@@ -129,7 +130,7 @@
                                            uint32 numOutEdges, 
                                            double cnt) {
 
-    Node *node = new(mm) Node(mm, cfg.getNextNodeId(), (uint32) cnt, NODE_DISPATCH);
+    Node *node = new(mm) Node(mm, opndManager->getNextNodeId(), (uint32) cnt, NODE_DISPATCH);
     nodes.push_back(node);
 
     IPF_LOG << endl << "    Generate Dispatch node" << node->getId() << endl;
@@ -144,7 +145,7 @@
                                     BlockCodeSelector &codeSelector, 
                                     double            cnt) {
 
-    BbNode *node = new(mm) BbNode(mm, cfg.getNextNodeId(), (uint32)cnt);
+    BbNode *node = new(mm) BbNode(mm, opndManager->getNextNodeId(), (uint32)cnt);
 
     nodes.push_back(node);
     if(blockKind == Prolog) cfg.setEnterNode(node);
@@ -162,7 +163,7 @@
                                           uint32 numOutEdges, 
                                           double cnt) {
 
-    Node *node = new(mm) Node(mm, cfg.getNextNodeId(), (uint32) cnt, NODE_UNWIND);
+    Node *node = new(mm) Node(mm, opndManager->getNextNodeId(), (uint32) cnt, NODE_UNWIND);
     nodes.push_back(node);
 
     IPF_LOG << endl << "    Generate Unwind node" << node->getId() << endl;
@@ -173,7 +174,7 @@
 
 uint32 IpfCfgCodeSelector::genExitNode(uint32 numInEdges, double cnt) {
 
-    BbNode *node = new(mm) BbNode(mm, cfg.getNextNodeId(), (uint32) cnt);
+    BbNode *node = new(mm) BbNode(mm, opndManager->getNextNodeId(), (uint32) cnt);
     nodes.push_back(node);
     cfg.setExitNode(node);
 
@@ -265,6 +266,7 @@
 }
 
 //--------------------------------------------------------------------------------//
+// edge from try region to dispatch node 
 
 void IpfCfgCodeSelector::genExceptionEdge(uint32 tailNodeId, 
                                           uint32 headNodeId, 
@@ -273,13 +275,14 @@
     Node *tailNode = nodes[tailNodeId];
     Node *headNode = nodes[headNodeId];
 
-    IPF_LOG << "    Generate Exception     edge node" << tailNodeId;
-    IPF_LOG << " -> node" << headNodeId << endl;
+    IPF_LOG << "    Generate Exception     edge node" << tailNode->getId();
+    IPF_LOG << " -> node" << headNode->getId() << endl;
     Edge *edge = new(mm) Edge(tailNode, headNode, prob, EDGE_DISPATCH);
     edge->insert();
 }
 
 //----------------------------------------------------------------------------------------//
+// edge from dispatch node to exception handler 
 
 void IpfCfgCodeSelector::genCatchEdge(uint32  tailNodeId, 
                                       uint32  headNodeId, 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp Wed Apr 11 05:28:45 2007
@@ -1688,9 +1688,7 @@
     p[1] |= s[2] << 23;
 
     // write to callAddr
-    VMInterface::rewriteCodeBlock((Byte *)callAddr, 
-                                              (Byte *)p,
-                                              IPF_BUNDLE_SIZE);
+    VMInterface::rewriteCodeBlock((Byte *)callAddr, (Byte *)p, IPF_BUNDLE_SIZE);
 
 //    IPF_LOG << "Patch brl.call to 0x" << hex
 //            << (uint64)methodAddr << " at 0x" << (uint64)callAddr << "\n"

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp Wed Apr 11 05:28:45 2007
@@ -53,7 +53,6 @@
     compilationInterface(compilationInterface_) {
 
     opndManager = cfg.getOpndManager();
-    numFpInArgs = 0;
     p0          = opndManager->getP0();
 }
 
@@ -689,7 +688,7 @@
 
 CG_OpndHandle *IpfInstCodeSelector::convToInt(ConvertToIntOp::Types       opType,
                                               bool                        isSigned,
-					      bool                        isZeroExtend,
+                                              bool                        isZeroExtend,
                                               ConvertToIntOp::OverflowMod ovfMod,
                                               Type                        *dstType, 
                                               CG_OpndHandle               *src_) {
@@ -968,25 +967,21 @@
 
 CG_OpndHandle *IpfInstCodeSelector::defArg(uint32 inArgPosition, Type *type) {
 
-    DataKind dataKind = toDataKind(type->tag);
-    OpndKind opndKind = toOpndKind(type->tag);
-    int32    location = LOCATION_INVALID;
-    bool     isFp     = type->isFloatingPoint();
 
-    if (inArgPosition < MAX_REG_ARG) {
-        if (isFp) location = F_INARG_BASE + numFpInArgs++;
-        else      location = opndManager->newInReg(inArgPosition);
-    } else {
-        location = opndManager->newInSlot(inArgPosition); // location is area local offset
-    }
+    OpndKind opndKind = toOpndKind(type->tag);
+    DataKind dataKind = toDataKind(type->tag);
     
-    RegOpnd *arg = opndManager->newRegOpnd(opndKind, dataKind, location);
+    Opnd *arg = opndManager->newInArg(opndKind, dataKind, inArgPosition);    
     IPF_LOG << "      defArg " << IrPrinter::toString(arg) << " " << type->getName() << endl;
 
-    if (isFp) {
-        RegOpnd *newarg = opndManager->newRegOpnd(opndKind, dataKind);
-        addNewInst(INST_MOV, p0, newarg, arg);            // if fp arg crosses call site
+    if (arg->isFloating()) {
+        BbNode  *prologNode = opndManager->getPrologNode();
+        RegOpnd *newarg     = opndManager->newRegOpnd(opndKind, dataKind);
+        Inst    *inst       = new(mm) Inst(mm, INST_MOV, p0, newarg, arg);
+        prologNode->addInst(inst);
         arg = newarg;                                     // it will be moved on preserved reg
+
+        IPF_LOG << "        " << IrPrinter::toString(inst) << endl;
     }
 
     return arg;

Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp?view=auto&rev=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp Wed Apr 11 05:28:45 2007
@@ -0,0 +1,170 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+                                                                                                            
+/**
+ * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
+ * @version $Revision: 1.1 $
+ *
+ */
+
+#include "IpfInstrumentator.h"
+#include "IpfIrPrinter.h"
+#include "open/vm.h"
+#include <fstream>
+
+namespace Jitrino {
+namespace IPF {
+
+//========================================================================================//
+// IrPrinter
+//========================================================================================//
+
+Instrumentator::Instrumentator(Cfg &cfg) : 
+    mm(cfg.getMM()), 
+    opndManager(cfg.getOpndManager()), 
+    cfg(cfg) {
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::instrument() {
+
+    instrumentStart();
+    instrumentEnd();
+    opndManager->setContainCall(true);
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::instrumentStart() {
+
+    InstVector instCode(mm);
+    uint64 funcDescPtr = (uint64) Instrumentator::methodStart;   // get function descriptor address
+
+    genNativeCall(funcDescPtr, instCode);
+
+    BbNode     *enterNode  = cfg.getEnterNode();
+    InstVector &insts      = enterNode->getInsts();
+    insts.insert(insts.end(), instCode.begin(), instCode.end());
+    IPF_LOG << endl << "  Method start:" << endl << IrPrinter::toString(instCode);
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::instrumentEnd() {
+
+    InstVector instCode(mm);
+    uint64 funcDescPtr = (uint64) Instrumentator::methodEnd;        // get function descriptor address
+    genNativeCall(funcDescPtr, instCode);                           // gen call of "methodEnd"
+
+    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);              // get nodes
+    for(uint16 i=0; i<nodes.size(); i++) {                          // iterate through CFG nodes
+
+        if (nodes[i]->getNodeKind() != NODE_BB)          continue;  // ignore non BB node
+
+        BbNode *node = (BbNode *)nodes[i];
+        InstVector &insts = node->getInsts();                       // get node's insts
+        if (insts.size() == 0)                           continue;  //
+        CompVector &comps = insts.back()->getComps();               // get last inst completers
+        if (comps.size()<1 || comps[0]!=CMPLT_BTYPE_RET) continue;  // if the inst is not "ret" - ignore
+
+//        MethodDesc *methodDesc = cfg.getMethodDesc();
+//        Type *type = methodDesc->getMethodSig()->getReturnType();
+//        
+//        if (type->isVoid()) {
+            insts.insert(insts.end()-1, instCode.begin(), instCode.end());
+//        } else {
+//            insts.insert(insts.end()-2, instCode.begin(), instCode.end());
+//        }
+    }
+        
+    IPF_LOG << endl << "  Method end:" << endl << IrPrinter::toString(instCode);
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::genNativeCall(uint64 funcDescPtr, InstVector &insts) {
+
+/*
+    DrlVMMethodDesc *methodDesc  = (DrlVMMethodDesc *) cfg.getMethodDesc();
+    Method_Handle   methodHandle = methodDesc->getDrlVMMethod();
+
+    Opnd *methodDescAddr = opndManager->newImm((uint64) methodHandle);
+    Opnd *p0             = opndManager->getP0();
+    Opnd *r0             = opndManager->getR0();
+    Opnd *b0             = opndManager->getB0();
+    Opnd *r1             = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, 1);
+    Opnd *funDescAddr    = opndManager->newImm(funcDescPtr);
+    Opnd *globalPtrAddr  = opndManager->newImm(funcDescPtr + 8);
+    Opnd *entryPointer   = opndManager->newRegOpnd(OPND_G_REG, DATA_U64);
+    Opnd *globalPtrBak   = opndManager->newRegOpnd(OPND_G_REG, DATA_U64);
+    Opnd *globalPtr      = opndManager->newRegOpnd(OPND_G_REG, DATA_U64);
+    Opnd *callTgt        = opndManager->newRegOpnd(OPND_B_REG, DATA_U64);
+    Opnd *callArg        = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, opndManager->newOutReg(0));
+
+    // load entry pointer
+    insts.push_back(new(mm) Inst(mm, INST_MOVL, p0, entryPointer, funDescAddr));
+    insts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, entryPointer, entryPointer));
+
+    // save global pointer
+    insts.push_back(new(mm) Inst(mm, INST_MOV, p0, globalPtrBak, r1));
+    
+    // load new global pointer
+    insts.push_back(new(mm) Inst(mm, INST_MOVL, p0, globalPtr, globalPtrAddr));
+    insts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, r1, globalPtr));
+
+    // make call
+    insts.push_back(new(mm) Inst(mm, INST_MOVL, p0, callArg, methodDescAddr));
+    insts.push_back(new(mm) Inst(mm, INST_MOV, p0, callTgt, entryPointer));
+    insts.push_back(new(mm) Inst(mm, INST_BR13, CMPLT_BTYPE_CALL, p0, r0, b0, callTgt, callArg, r1));
+
+    // restore global pointer
+    insts.push_back(new(mm) Inst(mm, INST_MOV, p0, r1, globalPtrBak));
+    insts.push_back(new(mm) Inst(mm, INST_USE, p0, r1));
+    */
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::methodStart(Method_Handle methodHandle) {
+
+    ofstream rtLog;
+    rtLog.open("rt.log", ios::out | ios::app);
+
+    rtLog << "Start ";
+    rtLog << class_get_name(method_get_class(methodHandle));
+    rtLog << "." << method_get_name(methodHandle);
+    rtLog << method_get_descriptor(methodHandle) << endl;
+    rtLog.close();
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Instrumentator::methodEnd(Method_Handle methodHandle) {
+
+    ofstream rtLog;
+    rtLog.open("rt.log", ios::out | ios::app);
+    
+    rtLog << "End   ";
+    rtLog << class_get_name(method_get_class(methodHandle));
+    rtLog << "." << method_get_name(methodHandle);
+    rtLog << method_get_descriptor(methodHandle) << endl;
+    rtLog.close();
+}
+
+} // IPF
+} // Jitrino

Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInstrumentator.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp Wed Apr 11 05:28:45 2007
@@ -21,6 +21,8 @@
  */
 
 #include "IpfIrPrinter.h"
+#include "CompilationContext.h"
+#include "PMFAction.h"
 
 namespace Jitrino {
 namespace IPF {
@@ -39,12 +41,24 @@
     mm(cfg_.getMM()),
     cfg(cfg_),
     ofs(NULL) {
+    
+    if (Log::isEnabled() == false) return;
+
+    CompilationContext *cc        = CompilationContext::getCurrentContext();
+    SessionAction      *session   = cc->getCurrentSessionAction();
+    LogStream          &logStream = session->log(LogStream::CT);
+    strcpy(logDir, logStream.getFileName());
+    int len = strlen(logDir);
+    logDir[len - 6] = 0;
 }
 
 //----------------------------------------------------------------------------------------//
 
-void IrPrinter::printLayoutDot(char *logName) {
+void IrPrinter::printLayoutDot(char *logFile) {
 
+    char logName[500];
+    strcpy(logName, logDir);
+    strcat(logName, logFile);
     ofs = new(mm) ofstream(logName);
     
     BbNode *node = (BbNode *)cfg.getEnterNode();
@@ -66,8 +80,11 @@
 
 //----------------------------------------------------------------------------------------//
 
-void IrPrinter::printCfgDot(char *logName) {
+void IrPrinter::printCfgDot(char *logFile) {
 
+    char logName[500];
+    strcpy(logName, logDir);
+    strcat(logName, logFile);
     ofs = new(mm) ofstream(logName);
     
     NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);
@@ -90,7 +107,7 @@
     
     os = &os_;
     
-    BbNode *node = (BbNode *)cfg.getEnterNode();
+    BbNode *node = cfg.getEnterNode();
     
     *os << endl;
     *os << "----------- Code dump ----------------------------------------" << endl;
@@ -164,7 +181,6 @@
     *ofs << "  fontpath=\"c:\\winnt\\fonts\";" << ::std::endl;
     *ofs << "  node [shape=record,fontname=\"Courier\",fontsize=9];" << ::std::endl;
     *ofs << "  edge [fontname=\"Courier\",fontsize=9];" << ::std::endl;
-
 }
 
 //----------------------------------------------------------------------------------------//
@@ -327,6 +343,15 @@
 
 //----------------------------------------------------------------------------------------//
 
+string IrPrinter::toString(QpNode *qpNode) {
+    ostringstream oss;
+    oss << "mask: " << boolString(qpNode->getNodeMask()) << " comp: " << boolString(qpNode->getCompMask());
+    oss << " dead: " << boolString(qpNode->getLiveMask());
+    return oss.str();
+}
+
+//----------------------------------------------------------------------------------------//
+
 string IrPrinter::toString(OpndSet &opndSet) {
     
     ostringstream oss;
@@ -402,6 +427,21 @@
     
 //----------------------------------------------------------------------------------------//
 
+string IrPrinter::toString(MethodDesc *methodDesc) {
+
+    ostringstream oss;
+
+    if (methodDesc->getParentType() != NULL) {
+        oss << methodDesc->getParentType()->getName() << ".";
+    }
+    oss << methodDesc->getName();
+    oss << methodDesc->getSignatureString();
+
+    return oss.str();
+}
+
+//----------------------------------------------------------------------------------------//
+
 string IrPrinter::toString(NodeKind nodeKind) {
     
     string s;
@@ -485,6 +525,18 @@
 
     if (s.empty()) IPF_ERR << " unexpected dataKind " << dataKind << endl;
     return s;
+}
+
+//----------------------------------------------------------------------------//
+
+string IrPrinter::boolString(uint64 mask, uint16 size) {
+    uint64 m = 1 << size - 1; 
+    ostringstream oss;
+    for (int i=0; i<size; i++, m >>= 1) {
+        if (mask & m) oss << "1";
+        else          oss << "0";
+    }
+    return oss.str();
 }
 
 } // IPF

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp Wed Apr 11 05:28:45 2007
@@ -17,6 +17,7 @@
                                                                                                             
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
+ * @version $Revision: 1.2 $
  *
  */
 
@@ -31,139 +32,152 @@
 // LiveAnalyzer
 //========================================================================================//
 
-LiveAnalyzer::LiveAnalyzer(Cfg &cfg_) : cfg(cfg_) { }
+LiveAnalyzer::LiveAnalyzer(Cfg &cfg) : 
+    cfg(cfg),
+    mm(cfg.getMM()),
+    workSet(mm),
+    liveManager(cfg),
+    liveSet(liveManager.getLiveSet()),
+    dceFlag(false) {
+}
 
 //----------------------------------------------------------------------------------------//
 
-void LiveAnalyzer::makeLiveSets(bool verify_) {
+void LiveAnalyzer::analyze() {
     
-//    IPF_LOG << endl;
-    verify = verify_;
-    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);   // get postordered node list
-
-    // clear live sets for all nodes
-    if (!verify) {
-        for(uint16 i=0; i<nodes.size(); i++) {
-            nodes[i]->clearLiveSet();
+    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);  // get postordered node list
+    for (int16 i=nodes.size()-1; i>=0; i--) {           // iterate nodes
+        Node *node = nodes[i];                          //
+        node->setVisited(false);                        // mark node unvisited
+        if (dceFlag == false) node->clearLiveSet();     // clear node's live set
+        workSet.push_back(node);                        // put node in workSet (reverse order)
+    }
+
+    while (workSet.size() > 0) {                        // while there is node to analyze
+        Node *node = workSet.back();                    // get last workSet node
+        node->setVisited(true);                         // mark the node visited
+        workSet.pop_back();                             // remove the node from workSet
+        if (analyzeNode(node) == false) {               // node's live set has changed - live sets of predecessor need evaluation
+            pushPreds(node);                            // put predecessors in workSet
         }
     }
     
-    // make new live sets for all nodes
-    bool flag = true;
-    while (flag == true) {
-        flag = false;
-        for(uint16 i=0; i<nodes.size(); i++) {
-            if (analyzeNode(nodes[i]) == false) flag = true;
-        }
-    }
+    if (VERIFY_ON) verify();
 }
 
 //----------------------------------------------------------------------------------------//
 
-bool LiveAnalyzer::analyzeNode(Node *node) {
-
-    // build live set for node
-    RegOpndSet currLiveSet(cfg.getMM());
-    RegOpndSet &oldLiveSet = node->getLiveSet();
-    node->mergeOutLiveSets(currLiveSet);          // put in the live set merged live sets of successors
-
-//    if (LOG_ON) {
-//        IPF_LOG << "    node" << node->getId() << " successors:";
-//        EdgeVector &edges = node->getOutEdges();
-//        for (uint16 i=0; i<edges.size(); i++) {
-//            Node *succ       = edges[i]->getTarget();
-//            Node *loopHeader = succ->getLoopHeader();
-//            IPF_LOG << " " << succ->getId();
-//            if (loopHeader != NULL) IPF_LOG << "(" << loopHeader->getId() << ")";
-//        }
-//        IPF_LOG << " exit live set: " << IrPrinter::toString(currLiveSet) << endl;
-//    }
+void LiveAnalyzer::dce() {
 
-    // If node is not BB - currLiveSet is not going to change 
-    if(node->getNodeKind() != NODE_BB) {
-//        IPF_LOG << "      node is not BB - live set is not changed" << endl;
-        if (oldLiveSet == currLiveSet) return true;     // if live set has not changed - nothing to do
-
-        node->setLiveSet(currLiveSet);            // Set currLiveSet for the current node
-        return false;                                   // and continue
-    }
+    IPF_LOG << endl << "  Dead code:" << endl;
+    dceFlag = true;
+    analyze();
+    dceFlag = false;
+}
+    
+//----------------------------------------------------------------------------------------//
+// check if node's liveSets coincide with calculated ones
+// check if liveSet of Enter node is empty (except inArgs including implicit arg b0)
 
-    InstVector   &insts    = ((BbNode *)node)->getInsts();
-    InstIterator currInst  = insts.end()-1;
-    InstIterator firstInst = insts.begin()-1;
+void LiveAnalyzer::verify() {
+    
+    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);              // get nodes postorder
     
-    for(; currInst>firstInst; currInst--) {
-        updateLiveSet(currLiveSet, *currInst);
+    for (uint16 i=0; i<nodes.size(); i++) {                         // iterate it
+        if (analyzeNode(nodes[i]) == false) {                       // if node's liveSet does not coincide with calculated one
+            IPF_ERR << " node" << nodes[i]->getId() << endl;        // throw error message
+        }
     }
     
-    if (oldLiveSet == currLiveSet) return true;     // if live set has not changed - nothing to do
-    if (verify) {
-        IPF_LOG << "ERROR node" << node->getId() << endl;
-        IPF_LOG << " old live set: " << IrPrinter::toString(oldLiveSet) << endl;
-        IPF_LOG << " new live set: " << IrPrinter::toString(currLiveSet) << endl;
+    RegOpndSet    enterLiveSet = cfg.getEnterNode()->getLiveSet();  // get liveSet of Enter node
+    RegOpndVector &inArgs      = cfg.getOpndManager()->getInArgs(); // get inArgs
+    for (uint16 i=0; i<inArgs.size(); i++) {                        //
+        enterLiveSet.erase(inArgs[i]);                              // remove inArgs from enterLiveSet
+    }                                                               // 
+    
+    enterLiveSet.erase(cfg.getOpndManager()->getB0());              // remove b0 from enterLiveSet
+    if (enterLiveSet.size() == 0) return;                           // if enterLiveSet is empty - Ok
+
+    IPF_ERR << " size " << enterLiveSet.size() << endl;
+    for (RegOpndSet::iterator it=enterLiveSet.begin(); it!=enterLiveSet.end(); it++) {
+        IPF_ERR << " alive opnd on method enter " << IrPrinter::toString(*it)
+            << " " << IrPrinter::toString(cfg.getMethodDesc()) << endl;
     }
-    node->setLiveSet(currLiveSet);                  // set currLiveSet for the current node
-    return false;
 }
 
 //----------------------------------------------------------------------------------------//
-// Remove dst and insert qp and src opnds in live set. 
-// If qp is not "p0" do not remove dst opnd from live set, 
-// because if the inst is not executed dst opnd will stay alive
-
-void LiveAnalyzer::updateLiveSet(RegOpndSet &liveSet, Inst *inst) {
+// recalculate live set for the node
+// if it has not changed - return true, else - return false
 
-    OpndVector &opnds = inst->getOpnds();            // get instruction's opnds
-    uint16     numDst = inst->getNumDst();           // number of dst opnds (qp has index 0)
-    bool       isP0   = (opnds[0]->getValue() == 0); // is instruction qp is p0
+bool LiveAnalyzer::analyzeNode(Node *node) {
 
-    // remove dst opnds from live set
-    for(uint16 i=1; isP0 && i<=numDst; i++) {
-        if (opnds[i]->isWritable()) liveSet.erase((RegOpnd *)opnds[i]);
+    liveManager.init(node);                      // init LiveManager with current node
+    if (LOG_ON) {
+        IPF_LOG << endl << "  Qp Tree for node" << node->getId() << endl;
+        liveManager.printQpTree();
+    }
+    
+    RegOpndSet &oldLiveSet = node->getLiveSet(); // get current node live set (on node enter)
+    if (node->getNodeKind() != NODE_BB) {        // liveSet is not going to change 
+        if (oldLiveSet == liveSet) return true;  // if live set has not changed - nothing to do
+        node->setLiveSet(liveSet);               // set liveSet for the current node
+        return false;                            // live set of the node has changed
+    }
+
+    InstVector &insts = ((BbNode *)node)->getInsts();
+    for(int16 i=insts.size()-1; i>=0; i--) {     // iterate through node insts postorder
+        Inst *inst = insts[i];                   //
+        if (dceFlag && isInstDead(inst)) {       // if dce is activated and inst is dead
+            IPF_LOG << "    node" << setw(3) << left << node->getId();
+            IPF_LOG << IrPrinter::toString(inst) << endl;
+            insts.erase(insts.begin()+i);        // remove inst from InstVector of current node
+            liveManager.def(inst);               // change liveSet according with inst def
+        } else {                                 //
+            liveManager.def(inst);               // change liveSet according with inst def
+            liveManager.use(inst);               // change liveSet according with inst use
+        }
     }
     
-    // insert qp opnd in live set
-    if (opnds[0]->isWritable()) liveSet.insert((RegOpnd *)opnds[0]);
-    
-    // insert src opnds in live set
-    for(uint16 i=numDst+1; i<opnds.size(); i++) {
-        if (opnds[i]->isWritable()) liveSet.insert((RegOpnd *)opnds[i]);     
-    } 
-}    
+    if (oldLiveSet == liveSet) return true;      // if live set has not changed - nothing to do
+    node->setLiveSet(liveSet);                   // set liveSet for the current node
+    return false;                                // live set of the node has changed
+}
 
 //----------------------------------------------------------------------------------------//
-// Remove dst opnds from live set. 
-// If qp is not "p0" do not remove dst opnd from live set, 
-// because if the inst is not executed dst opnd will stay alive
+// push all predecessors of the node in workSet (ignore preds which are in workSet already)
 
-void LiveAnalyzer::defOpnds(RegOpndSet &liveSet, Inst *inst) {
+void LiveAnalyzer::pushPreds(Node *node) {
 
-    OpndVector &opnds = inst->getOpnds();            // get instruction's opnds
-    uint16     numDst = inst->getNumDst();           // number of dst opnds (qp has index 0)
-    bool       isP0   = (opnds[0]->getValue() == 0); // is instruction qp is p0
-
-    // remove dst opnds from live set
-    for(uint16 i=1; isP0 && i<=numDst; i++) {
-        if (opnds[i]->isWritable()) liveSet.erase((RegOpnd *)opnds[i]);
+    EdgeVector &edges = node->getInEdges();       // get in edges
+    for (uint16 i=0; i<edges.size(); i++) {       // iterate
+        Node *pred = edges[i]->getSource();       // get predecessor
+        if (pred->isVisited() == false) continue; // if predecessor is in workSet - ignore
+        workSet.push_back(pred);                  // push predecessor in workSet
+        pred->setVisited(false);                  // mark it unvisited
     }
-}    
+}
 
 //----------------------------------------------------------------------------------------//
-// Insert qp and src opnds in live set. 
+// Check if instruction can be removed from inst vector. 
+// Do not remove instruction having "side effects" (like "call")
 
-void LiveAnalyzer::useOpnds(RegOpndSet &liveSet, Inst *inst) {
+bool LiveAnalyzer::isInstDead(Inst *inst) {
+    
+    if (inst->isCall())                    return false; // "call" inst is never dead
+    if (inst->getInstCode() == INST_ALLOC) return false; // "alloc" inst is never dead
 
-    OpndVector &opnds = inst->getOpnds();                          // get instruction's opnds
-    uint16     numDst = inst->getNumDst();                         // number of dst opnds (qp has index 0)
+    uint16 numDst = inst->getNumDst();                   // get num of dst opnds
+    if (numDst == 0) return false;                       // if there is no dst opnds - ignore
 
-    // insert qp opnd in live set
-    if (opnds[0]->isWritable()) liveSet.insert((RegOpnd *)opnds[0]);
-    
-    // insert src opnds in live set
-    for(uint16 i=numDst+1; i<opnds.size(); i++) {
-        if (opnds[i]->isWritable()) liveSet.insert((RegOpnd *)opnds[i]);     
-    } 
-}    
+    OpndVector &opnds = inst->getOpnds();                // get inst opnds
+    RegOpnd    *qp    = (RegOpnd *)opnds[0];             // get qp of the inst
+    QpMask     mask   = liveManager.getLiveMask(qp);     // get mask for this qp space
+    for (uint16 i=1; i<numDst+1; i++) {                  // iterate dst opnds
+        RegOpnd *dst = (RegOpnd *)opnds[i];              // 
+        if (dst->isAlive(mask)) return false;            // if dst is alive - inst is alive
+    }
+    return true;                                         // there is no alive dst opnd - inst is dead
+}
 
 } // IPF
 } // Jitrino

Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp?view=auto&rev=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp Wed Apr 11 05:28:45 2007
@@ -0,0 +1,332 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+                                                                                                            
+/**
+ * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
+ * @version $Revision: 1.1 $
+ *
+ */
+
+#include "IpfLiveAnalyzer.h"
+#include "IpfIrPrinter.h"
+#include "IpfOpndManager.h"
+
+namespace Jitrino {
+namespace IPF {
+
+//========================================================================================//
+// QpNode
+//========================================================================================//
+
+QpNode::QpNode(QpNode *predNode, QpMask nodeMask) : 
+    predNode(predNode), 
+    compNode(NULL), 
+    nodeMask(nodeMask), 
+    compMask(0),
+    liveMask(0) {
+
+    QpNode *qpNode = predNode;
+    while (qpNode != NULL) {            // iterate through all predecessors of the node
+        qpNode->orNodeMask(nodeMask);   // add bits of this nodeMask in predecessor's nodeMasks
+        qpNode = qpNode->getPredNode(); // get next predecessor
+    }
+}
+
+//----------------------------------------------------------------------------------------//
+// make mask of all predicate spaces interfering with current one. These are all spaces
+// except complementing ones
+
+void QpNode::initLiveMask() {
+    
+    QpNode *qpNode = this;
+    liveMask = 0;
+    while (qpNode != NULL) {
+        QpMask mask = qpNode->getCompMask();        // get nodeMask of complemening to current space
+        if (mask != MAX_QP_MASK) liveMask |= mask;  // if there is complementing space (is not MAX_QP_MASK) - add masks
+        qpNode = qpNode->getPredNode();             // get next predecessor
+    }                                               //
+    liveMask = ~liveMask;                           // this qpNode interfere with all others except complementing ones
+}
+
+//----------------------------------------------------------------------------------------//
+// if qpNode has complement node - get its nodeMask (just to speed up "getCompMask" method)
+// else - set all ones in compMask
+
+void QpNode::initCompMask() { 
+    
+    if (compNode == NULL) compMask = MAX_QP_MASK;
+    else                  compMask = compNode->getNodeMask(); 
+}
+
+//========================================================================================//
+// QpTree
+//========================================================================================//
+
+QpTree::QpTree(Cfg &cfg) : 
+    cfg(cfg),
+    mm(cfg.getMM()),
+    qpMap(mm),
+    slot(0),
+    p0(cfg.getOpndManager()->getP0()) {
+
+    qpMap.insert( make_pair(p0, new(mm) QpNode(NULL, MAX_QP_MASK)) );  // make root qpNode
+}
+
+//----------------------------------------------------------------------------------------//
+// build qpMap determining qp->qpNode relations. If qp is defined several times - the tree 
+// contains several entryes corresponding to the qp.
+
+void QpTree::makeQpTree(InstVector &insts) {
+    
+    IPF_ASSERT(qpMap.size() == 1);
+    
+    slot = 1;                                                  // init slot (position in mask)
+    for (InstVector::iterator it=insts.begin(); it!=insts.end(); it++) {
+        Inst *inst = *it;                                      // iterate insts
+
+        if (isDefOnePred(inst)) {                              // if inst defs one predicate opnd
+            OpndVector &opnds = inst->getOpnds();              // get opnds of the inst
+            QpNode     *qpNode = findQpNode(opnds[0]);         // inst qp is predecessor for predicates defined in the inst
+            makeQpNode(qpNode, opnds[2]);                      // make qpNode for the predicate opnd (it is always second one)
+            continue;
+        }
+
+        if (isDefTwoPreds(inst)) {                             // if inst defs two predicate opnds
+            OpndVector &opnds = inst->getOpnds();              // get opnds of the inst
+            QpNode     *qpNode = findQpNode(opnds[0]);         // inst qp is predecessor for predicates defined in the inst
+            QpNode     *p1Node = makeQpNode(qpNode, opnds[1]); // make qpNode for first predicate opnd
+            QpNode     *p2Node = makeQpNode(qpNode, opnds[2]); // make qpNode for second predicate opnd
+            
+            if (isDefComps(inst) == false) continue;           // inst does not define mutually complemen predicates - continue
+            if (p1Node != NULL) p1Node->setCompNode(p2Node);   // p2Node complements p1Node
+            if (p2Node != NULL) p2Node->setCompNode(p1Node);   // p1Node complements p2Node
+        }
+    }    
+
+    for (QpMap::iterator it=qpMap.begin(); it!=qpMap.end(); it++) {
+        QpNode *qpNode = it->second;                           // iterate all qpNodes in the tree
+        qpNode->initCompMask();                                // set comp mask (to speed up getCompMask)
+    }
+
+    for (QpMap::iterator it=qpMap.begin(); it!=qpMap.end(); it++) {
+        QpNode *qpNode = it->second;                           // iterate all qpNodes in the tree
+        qpNode->initLiveMask();                                // set live masks (predicate spaces which do not complement)
+    }
+}
+
+//----------------------------------------------------------------------------------------//
+// find qpNode corresponding to "qp" from qpMap. There are can be several nodes 
+// corresponding to one qp. We should return least recent inserted one
+
+QpNode* QpTree::findQpNode(Opnd *qp) {
+    
+    QpMap::iterator it = qpMap.upper_bound(qp);
+    return (--it)->second;
+}
+
+//----------------------------------------------------------------------------------------//
+// remove qpNode corresponding to "qp" from qpMap. There are can be several nodes 
+// corresponding to one qp. We should remove least recent inserted one
+
+void QpTree::removeQpNode(Opnd *qp) {
+    
+    QpMap::iterator it = qpMap.upper_bound(qp);    // find in qpMap last node corresponding to "qp"
+    qpMap.erase(--it);                             // remove the node from the tree
+}
+
+//----------------------------------------------------------------------------------------//
+
+void QpTree::printQpTree() {
+    
+    QpMap::iterator it = qpMap.upper_bound(p0);
+    printQpNode(--it, 0);
+}
+
+//----------------------------------------------------------------------------------------//
+
+QpNode* QpTree::makeQpNode(QpNode *predNode, Opnd *qp) {
+    
+    if (qp == p0) return NULL;                       // node for p0 has been created in constructor
+    slot <<= 1;                                      // get next empty slot (position in mask)
+    QpNode *qpNode = new(mm) QpNode(predNode, slot); // create qpNode
+    qpMap.insert( make_pair(qp, qpNode) );           // insert the qpNode in qpTree
+    return qpNode;
+}
+
+//----------------------------------------------------------------------------------------//
+
+void QpTree::printQpNode(QpMap::iterator nodeIt, uint16 level) {
+    
+    QpNode *predNode = nodeIt->second;
+    Opnd   *qp       = nodeIt->first;
+    IPF_LOG << "    " << IrPrinter::toString(predNode);
+    for (uint16 i=0; i<level; i++) IPF_LOG << "  ";
+    IPF_LOG << "    " << IrPrinter::toString(qp) << endl;
+    
+    for (QpMap::iterator it=qpMap.begin(); it!=qpMap.end(); it++) {
+        QpNode *qpNode = it->second;
+        if (qpNode->getPredNode() != predNode) continue;
+        printQpNode(it, level+1);
+    }
+}
+
+//----------------------------------------------------------------------------------------//
+// return true if the inst defines one pred opnd
+
+bool QpTree::isDefOnePred(Inst *inst) {
+    
+    switch (inst->getInstCode()) {
+        case INST_FRCPA    : 
+        case INST_FPRCPA   : 
+        case INST_FRSQRTA  : 
+        case INST_FPRSQRTA : return true;
+        default            : return false;
+    }
+}
+
+//----------------------------------------------------------------------------------------//
+// return true if the inst defines two pred opnds
+
+bool QpTree::isDefTwoPreds(Inst *inst) {
+    
+    switch (inst->getInstCode()) {
+        case INST_CMP    : 
+        case INST_CMP4   : 
+        case INST_FCMP   : 
+        case INST_TBIT   : 
+        case INST_TNAT   : 
+        case INST_FCLASS : return true;
+        default          : return false;
+    }
+}
+
+//----------------------------------------------------------------------------------------//
+// return true if the inst defines two mutually complement preds
+
+bool QpTree::isDefComps(Inst *inst) {
+    
+    InstCode instCode = inst->getInstCode();
+    if (instCode == INST_FCMP || instCode == INST_FCLASS) return true;
+    if (instCode == INST_TBIT || instCode == INST_TNAT)   return true;
+    
+    CompVector &comps = inst->getComps();
+    if (comps.size() < 2)                 return true;
+    if (comps[1] == CMPLT_CMP_CTYPE_NONE) return true;
+    if (comps[1] == CMPLT_CMP_CTYPE_UNC)  return true;
+    return false;
+}
+
+//========================================================================================//
+// LiveManager
+//========================================================================================//
+
+LiveManager::LiveManager(Cfg &cfg) : 
+    cfg(cfg),
+    qpTree(cfg),
+    liveSet(cfg.getMM()) {
+}
+
+//----------------------------------------------------------------------------------------//
+
+void LiveManager::init(Node *node) {
+    
+    liveSet.clear();                                 // clear live set
+    node->mergeOutLiveSets(liveSet);                 // all opnds alive in successors are alive in current live set
+
+    for (RegOpndSet::iterator it=liveSet.begin(); it!=liveSet.end(); it++) {
+        RegOpnd *opnd = *it;                         //
+        opnd->orQpMask(MAX_QP_MASK);                 // initially opnds alive in all pred spaces
+    }                                                //
+
+    if (node->getNodeKind() != NODE_BB) return;      // if node is not BB - nothing to do
+    qpTree.makeQpTree(((BbNode *)node)->getInsts()); // make qpTree for current BB
+}
+
+//----------------------------------------------------------------------------------------//
+// add opnds used in the inst in liveSet. Or modify opnd's qpMask to reflect use under inst's qp
+
+void LiveManager::use(Inst *inst) {
+
+    OpndVector &opnds  = inst->getOpnds();      // get inst's opnds
+    RegOpnd    *qp     = (RegOpnd *)opnds[0];   // fist opnd is instruction qp
+    QpNode     *qpNode = qpTree.findQpNode(qp); // find qpNode corresponding to the qp
+
+    if (qp->isWritable()) {
+        qp->orQpMask(MAX_QP_MASK);              // qp is alive in all pred spaces
+        liveSet.insert(qp);
+    }
+
+    for (uint16 i=inst->getNumDst()+1; i<opnds.size(); i++) {
+        RegOpnd *opnd = (RegOpnd *)opnds[i];
+        if (opnd->isWritable() == false) continue;
+        useOpnd(qpNode, opnd);
+        liveSet.insert(opnd);
+    }
+}
+    
+//----------------------------------------------------------------------------------------//
+// remove opnds defined in the inst from liveSet. Or modify opnd's qpMask to reflect def 
+// under inst's qp
+
+void LiveManager::def(Inst *inst) {
+
+    OpndVector &opnds  = inst->getOpnds();
+    RegOpnd    *qp     = (RegOpnd *)opnds[0];   // fist opnd is instruction qp
+    QpNode     *qpNode = qpTree.findQpNode(qp);
+
+    for (uint16 i=1; i<=inst->getNumDst(); i++) {
+        RegOpnd *opnd = (RegOpnd *)opnds[i];
+        if (opnd->isWritable()    == false) continue;
+        if (defOpnd(qpNode, opnd) == false) continue;
+        liveSet.erase(opnd);
+    }
+}
+    
+//----------------------------------------------------------------------------------------//
+
+QpMask LiveManager::getLiveMask(RegOpnd *opnd) {
+    QpNode *qpNode = qpTree.findQpNode(opnd);
+    return qpNode->getLiveMask();
+}
+
+//----------------------------------------------------------------------------------------//
+
+void LiveManager::useOpnd(QpNode *qpNode, RegOpnd *opnd) {
+    
+    QpMask mask = qpNode->getNodeMask();         // get mask of predicates alive in space of the qpNode
+    opnd->orQpMask(mask);                        // add mask to current opnd qpMask
+}
+
+//----------------------------------------------------------------------------------------//
+
+bool LiveManager::defOpnd(QpNode *qpNode, RegOpnd *opnd) {
+    
+    if (opnd->isQp()) qpTree.removeQpNode(opnd); // if we def predicate opnd - remove corresponding qpNode from qpTree
+    QpMask mask = opnd->getQpMask();             // get mask of pred spaces, the opnd alive in
+    if (mask == 0) return true;                  // if mask is zero - opnd is dead
+     
+    while ((mask & qpNode->getCompMask())==0) {  // while opnd is dead in complement predicate space - propagate def up
+        qpNode = qpNode->getPredNode();          // get predecessor in qpTree
+    }                                            // 
+
+    opnd->andQpMask(~(qpNode->getNodeMask()));   // null bits corresponding the successors in opnd's qp mask
+    if (opnd->getQpMask()) return false;         // opnd is alive in some predicate spaces
+    else                   return true;          // opnd is dead
+}
+
+} // IPF
+} // Jitrino

Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfLiveManager.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp Wed Apr 11 05:28:45 2007
@@ -230,10 +230,13 @@
 
 OpndManager::OpndManager(MemoryManager &mm, CompilationInterface &compilationInterface) : 
     mm(mm),
-    compilationInterface(compilationInterface) {
-
-    maxOpndId = 0;
+    compilationInterface(compilationInterface),
+    maxOpndId(0),
+    maxNodeId(0),
+    inArgs(mm) {
 
+    prologNode = new(mm) BbNode(mm, getNextNodeId(), 1);
+    
     r0  = NULL;
     f0  = NULL;
     f1  = NULL;
@@ -293,6 +296,37 @@
 
 //----------------------------------------------------------------------------------------//
 
+Opnd *OpndManager::newInArg(OpndKind opndKind, DataKind dataKind, uint32 inArgPosition) {
+
+    int32 location = LOCATION_INVALID;
+    bool  isFp     = IpfType::isFloating(dataKind);
+
+    if (inArgPosition < MAX_REG_ARG) {
+        if (isFp) location = F_INARG_BASE + getFpArgsNum();
+        else      location = newInReg(inArgPosition);
+    } else {
+        location = newInSlot(inArgPosition); // location is area local offset
+    }
+    
+    RegOpnd *arg = newRegOpnd(opndKind, dataKind, location);
+    inArgs.push_back(arg);
+    
+    return arg;
+}
+
+//----------------------------------------------------------------------------------------//
+
+uint16 OpndManager::getFpArgsNum() {
+    
+    uint16 fpArgsNum = 0;
+    for (uint16 i=0; i<inArgs.size(); i++) {
+        if (inArgs[i]->isFloating()) fpArgsNum ++;
+    }
+    return fpArgsNum;
+}
+
+//----------------------------------------------------------------------------------------//
+
 RegOpnd *OpndManager::getR0()  { if(r0 ==NULL) r0 =newRegOpnd(OPND_G_REG, DATA_I64,  0); return r0;  } 
 RegOpnd *OpndManager::getF0()  { if(f0 ==NULL) f0 =newRegOpnd(OPND_F_REG, DATA_F,    0); return f0;  } 
 RegOpnd *OpndManager::getF1()  { if(f1 ==NULL) f1 =newRegOpnd(OPND_F_REG, DATA_F,    1); return f1;  } 
@@ -340,6 +374,40 @@
 }
 
 //----------------------------------------------------------------------------------------//
+//   def       r32, r33, r8, r9
+//   alloc     pfsBak      = 1, 93, 2, 0      # gen alloc (pfsBak can not be preserved gr)
+//   adds      r12         = -stackSize, r12  # save SP
+//   adds      stackAddr   = offset, r12      # if pfsBak is stack opnd - spill pfs
+//   st8       [stackAddr] = pfsBak           #
+//   mov       scratch     = unat             # if we use preserved grs - spill unat
+//   adds      stackAddr   = offset, r12      #
+//   st8       [stackAddr] = scratch          #
+//   adds      stackAddr   = offset, r12      # spill preserved grs
+//   st8.spill [stackAddr] = preservedGr      #
+//   adds      stackAddr   = offset, r12      # spill preserved frs
+//   stf.spill [stackAddr] = preservedFr      #
+//   mov       brBak       = preservedBr      # save preserved brs
+//   mov       prBak       = pr               # save preserved prs
+//   mov       rpBak       = b0               # save return poiner
+//   mov       arg1        = r32
+//   mov       arg2        = r33
+//   mov       arg3        = r8
+//   mov       arg4        = r9
+//   movl      heapBase    = heapBaseImm
+//   movl      vtableBase  = vtableBaseImm
+
+void OpndManager::insertProlog(Cfg &cfg) {
+    
+    BbNode *enterNode = cfg.getEnterNode();
+    Edge   *edge      = new(mm) Edge(prologNode, enterNode, 1.0, EDGE_THROUGH);
+    edge->insert();
+    cfg.setEnterNode(prologNode);
+    cfg.search(SEARCH_UNDEF_ORDER);
+    
+    initCompBases(prologNode);
+}
+
+//----------------------------------------------------------------------------------------//
 
 void OpndManager::initCompBases(BbNode *enterNode) {
     
@@ -350,26 +418,18 @@
 
     if (heapBase != NULL) {
         baseValue  = (uint64) VMInterface::getHeapBase();
-        
         baseImm    = newImm(baseValue);
         Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, heapBase, baseImm);
-        insts.insert(insts.begin(), inst);
-        IPF_LOG << "    HeapBase initialization code inserted" << endl;
-    }
-    if (heapBaseImm != NULL) {
-        heapBaseImm->setValue((uint64)VMInterface::getHeapBase());
+        insts.insert(insts.end(), inst);
+        IPF_LOG << "    HeapBase saved on opnd " << IrPrinter::toString(heapBase) << endl;
     }
-        
+
     if (vtableBase != NULL) {
         baseValue  = (uint64) VMInterface::getVTableBase();
-
         baseImm    = newImm(baseValue);
         Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, vtableBase, baseImm);
-        insts.insert(insts.begin(), inst);
-        IPF_LOG << "    VtableBase initialization code inserted" << endl;
-    }
-    if (vtableBaseImm != NULL) {
-        vtableBaseImm->setValue((uint64)VMInterface::getVTableBase());
+        insts.insert(insts.end(), inst);
+        IPF_LOG << "    VtableBase saved on opnd " << IrPrinter::toString(vtableBase) << endl;
     }
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp Wed Apr 11 05:28:45 2007
@@ -23,7 +23,6 @@
 #include "IpfRegisterAllocator.h"
 #include "IpfIrPrinter.h"
 #include "IpfOpndManager.h"
-#include "IpfLiveAnalyzer.h"
 #include <fstream>
 
 namespace Jitrino {
@@ -38,10 +37,10 @@
 RegisterAllocator::RegisterAllocator(Cfg &cfg) : 
     mm(cfg.getMM()), 
     cfg(cfg),
+    opndManager(cfg.getOpndManager()),
+    liveManager(cfg),
     allocSet(mm),
-    liveSet(mm) {
-
-    opndManager = cfg.getOpndManager();
+    liveSet(liveManager.getLiveSet()) {
 }
 
 //----------------------------------------------------------------------------------------//
@@ -52,7 +51,7 @@
     buildInterferenceMatrix();
     removeSelfDep();
 
-    IPF_LOG << endl << "  Assign Locations" << endl;
+    IPF_LOG << endl << "  Assign Locations (# - cross call site)" << endl;
     assignLocations();
     
     IPF_LOG << endl << "  Remove Usless \"mov\" Instructions" << endl;
@@ -68,12 +67,11 @@
     NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);
     for(uint16 i=0; i<nodes.size(); i++) {                 // iterate through CFG nodes
 
-        if(nodes[i]->isBb() == false) continue;            // ignore non BB nodes
+        if(nodes[i]->isBb() == false) continue;              // ignore non BB nodes
 
-        liveSet.clear();                                   // clear live set
-        nodes[i]->mergeOutLiveSets(liveSet);               // put in the live set merged live sets of successors
+        BbNode *node = (BbNode *)nodes[i];
+        liveManager.init(node);
 
-        BbNode       *node       = (BbNode *)nodes[i];
         uint32       execCounter = node->getExecCounter();
         InstIterator currInst    = node->getInsts().end()-1;
         InstIterator firstInst   = node->getInsts().begin()-1;
@@ -81,21 +79,23 @@
         for (; currInst>firstInst; currInst--) {
 
             Inst        *inst  = *currInst;
-            uint16      numDst = inst->getNumDst();        // number of dst opnds (qp has index 0)
-            OpndVector& opnds  = inst->getOpnds();         // get inst's opnds
+            uint16      numDst = inst->getNumDst();          // number of dst opnds (qp has index 0)
+            OpndVector& opnds  = inst->getOpnds();           // get inst's opnds
+            RegOpnd     *qp    = (RegOpnd *) opnds[0];
+            QpMask      mask   = liveManager.getLiveMask(qp);
 
             checkCoalescing(execCounter, inst);
 
-            LiveAnalyzer::defOpnds(liveSet, inst);         // remove dst opnds from live set
-            checkCallSite(inst);                           // if currInst is "call" - all alive opnds cross call site
-            for(uint16 i=1; i<=numDst; i++) {              // for each dst opnd
-                updateAllocSet(opnds[i], execCounter);     // insert in allocSet and add live set in dep list
+            liveManager.def(inst);                           // remove dst opnds from live set
+            checkCallSite(inst, mask);                       // if currInst is "call" - all alive opnds cross call site
+            for(uint16 i=1; i<=numDst; i++) {                // for each dst opnd
+                updateAllocSet(opnds[i], execCounter, mask); // insert in allocSet and add live set in dep list
             }
             
-            LiveAnalyzer::useOpnds(liveSet, inst);         // add src opnds in live set
-            updateAllocSet(opnds[0], execCounter);         // insert in allocSet pq opnd and add alive qps in dep list
-            for (uint16 i=numDst+1; i<opnds.size(); i++) { // for each src opnd
-                updateAllocSet(opnds[i], execCounter);     // insert in allocSet and add live set in dep list
+            liveManager.use(inst);                           // add src opnds in live set
+            updateAllocSet(opnds[0], execCounter, mask);     // insert in allocSet pq opnd and add alive qps in dep list
+            for (uint16 i=numDst+1; i<opnds.size(); i++) {   // for each src opnd
+                updateAllocSet(opnds[i], execCounter, mask); // insert in allocSet and add live set in dep list
             }
         }
     }
@@ -127,16 +127,16 @@
 
 void RegisterAllocator::removeSelfDep() {
 
-    for(RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) {
+    for (RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) {
         (*it)->getDepOpnds().erase(*it);
     }
 
-    if(LOG_ON) { 
-        IPF_LOG << endl << "  Opnd dependensies " << endl; 
-        for(RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) {
+    if (LOG_ON) { 
+        IPF_LOG << endl << "  Opnd dependensies" << endl; 
+        for (RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) {
             RegOpnd *opnd = *it;
-            IPF_LOG << "      " << setw(4) << left << IrPrinter::toString(opnd) << " depends on: ";
-            IPF_LOG << IrPrinter::toString(opnd->getDepOpnds()) << endl;
+            IPF_LOG << "    " << setw(4) << left << IrPrinter::toString(opnd);
+            IPF_LOG << " depends on: " << IrPrinter::toString(opnd->getDepOpnds()) << endl;
         }
     }
 }
@@ -155,7 +155,8 @@
         RegOpnd *opnd = opndVector[i];
         if (opnd->getLocation() != LOCATION_INVALID) continue;    // opnd has already had location
     
-        IPF_LOG << "      " << left << setw(5) << IrPrinter::toString(opnd); 
+        IPF_LOG << "    " << left << setw(5) << IrPrinter::toString(opnd); 
+        IPF_LOG << (opnd->isCrossCallSite() ? "#" : " ");
         assignLocation(opnd);                 // assign location for current opnd
         IPF_LOG << " after assignment " << left << setw(5) << IrPrinter::toString(opnd);
         IPF_LOG << " spill cost: " << opnd->getSpillCost() << endl; 
@@ -163,8 +164,7 @@
 }
 
 //----------------------------------------------------------------------------------------//
-// remove useless move insts:
-// mov r8 = r8
+// remove useless move insts. Like this "mov r8 = r8"
 
 void RegisterAllocator::removeSameRegMoves() {
 
@@ -183,7 +183,7 @@
             if (dst->getValue() != src->getValue())       { it++; continue; } // if opnds allocated on different regs - ignore
             
             it = insts.erase(it);
-            IPF_LOG << "      node" << left << setw(4) << node->getId() << IrPrinter::toString(inst) << endl;
+            IPF_LOG << "    node" << left << setw(4) << node->getId() << IrPrinter::toString(inst) << endl;
         }
     }
 }
@@ -195,11 +195,10 @@
     
     OpndKind  opndKind    = target->getOpndKind();
     DataKind  dataKind    = target->getDataKind();
-    bool      isPreserved = target->getCrossCallSite();
+    bool      isPreserved = target->isCrossCallSite();
 
-    // build mask of used regs (already assigned opnds)
-    RegBitSet  usedMask;
-    RegOpndSet &depOpnds = target->getDepOpnds();
+    RegBitSet  usedMask;                                        // mask of regs which already used by dep opnds
+    RegOpndSet &depOpnds = target->getDepOpnds();               // target can not be assigned on reg used by depOpnds
     for (RegOpndSet::iterator it=depOpnds.begin(); it!=depOpnds.end(); it++) {
         RegOpnd *opnd = *it;
         int32 location = opnd->getLocation();                   // get location of dep opnd
@@ -207,25 +206,24 @@
         usedMask[location] = true;                              // mark reg busy
     }
 
-    // try to find opnd to coalesce on
-    Int2OpndMap &coalesceCands = target->getCoalesceCands();
+    Int2OpndMap &coalesceCands = target->getCoalesceCands();    // opnds used in inst like: move target = opnd
     for (Int2OpndMap::iterator it=coalesceCands.begin(); it!=coalesceCands.end(); it++) {
-        RegOpnd *opnd = it->second;
-        int32 location = opnd->getValue();
-        if (location > NUM_G_REG)                             continue;
-        if (isPreserved && (opnd->getCrossCallSite()==false)) continue;
-        if (usedMask[location] == true)                       continue;
-        target->setLocation(location);
+        RegOpnd *cls = it->second;
+        int32 location = cls->getValue();                       // get location of coalesce candidate 
+        if (location > NUM_G_REG)                   continue;   // opnd is not allocated (or allocated on stack)
+        if (isPreserved && !cls->isCrossCallSite()) continue;   // target must be preserved, but cls is scratch
+        if (usedMask[location] == true)             continue;   // target can not be allocated on cls location
+        target->setLocation(location);                          // assign target new location
         return;
     }
     
     int32 location = opndManager->newLocation(opndKind, dataKind, usedMask, isPreserved);
-    target->setLocation(location);                              // set location
+    target->setLocation(location);                              // assign target new location
 }    
 
 //----------------------------------------------------------------------------------------//
 
-void RegisterAllocator::updateAllocSet(Opnd *cand_, uint32 execCounter) {
+void RegisterAllocator::updateAllocSet(Opnd *cand_, uint32 execCounter, QpMask mask) {
 
     if (cand_->isReg()      == false) return;    // imm - it does not need allocation
     if (cand_->isMem()      == true)  return;    // mem stack - it does not need allocation
@@ -238,6 +236,7 @@
     // add current live set in opnd dep list (they must be placed on different regs)
     for (RegOpndSetIterator it=liveSet.begin(); it!=liveSet.end(); it++) {
         RegOpnd *opnd = *it;
+        if (opnd->isAlive(mask) == false) continue;
         cand->insertDepOpnd(opnd);               // cand depends on curr opnd from live set
         opnd->insertDepOpnd(cand);               // curr opnd from live set depends on cand
     }
@@ -246,15 +245,13 @@
 //----------------------------------------------------------------------------------------//
 // Check if current inst is "call" and mark all opnds in liveSet as crossing call site
 
-void RegisterAllocator::checkCallSite(Inst *inst) {
-
-    if(Encoder::isBranchCallInst(inst) == false) return; // opnd does not crass call site
+void RegisterAllocator::checkCallSite(Inst *inst, QpMask mask) {
 
-    IPF_LOG << "      these opnds cross call site: ";
-    IPF_LOG << IrPrinter::toString(liveSet) << endl;
-
-    for(RegOpndSetIterator it=liveSet.begin(); it!=liveSet.end(); it++) {
-        (*it)->setCrossCallSite(true);
+    if(inst->isCall() == false) return; // it is not call site
+    for(RegOpndSet::iterator it=liveSet.begin(); it!=liveSet.end(); it++) {
+        RegOpnd *opnd = *it;
+        if (opnd->isAlive(mask) == false) continue;
+        opnd->setCrossCallSite(true);
     }
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp?view=diff&rev=527470&r1=527469&r2=527470
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp Wed Apr 11 05:28:45 2007
@@ -124,35 +124,34 @@
 
 void RuntimeSupport::registerExceptionHandlers() {
     
-    Node       *dispatchNode = cfg.getEnterNode()->getDispatchNode();
     NodeVector &nodes        = cfg.search(SEARCH_LAYOUT_ORDER);
-    Byte       *startAddr    = (Byte *)((BbNode *)cfg.getEnterNode())->getAddress();
-
-    for(uint16 i=1; i<nodes.size(); i++) {
-        if(nodes[i]->getNodeKind() != NODE_BB) continue;    // ignore non BB node
-
-        if(dispatchNode != nodes[i]->getDispatchNode()) {
-            Byte *endAddr  = (Byte *)(((BbNode *)nodes[i])->getAddress());
-            Node *lastNode = nodes[i-1];
-
-            IPF_LOG << "    region detected, last node is BB" << lastNode->getId() << endl;
-            
-            makeRegion(startAddr, endAddr, dispatchNode);
-            startAddr    = (Byte *)((BbNode *)nodes[i])->getAddress();
-            dispatchNode = nodes[i]->getDispatchNode();
+    BbNode     *regionStart  = (BbNode *)nodes[0];
+    Node       *dispatchNode = regionStart->getDispatchNode();
+    
+    inserFakeLastNode(nodes);
+    for (uint16 i=1; i<nodes.size(); i++) {
+        if (nodes[i]->getNodeKind() != NODE_BB) continue; // ignore non BB node
+        BbNode *node = (BbNode *)nodes[i];
+
+        if (dispatchNode != node->getDispatchNode()) {    // if current node protected by another dispatch 
+            makeRegion(regionStart, node, dispatchNode);  // create new try region
+            regionStart  = node;                          // current node is first node of new region (if any)
+            dispatchNode = node->getDispatchNode();       // current dispatch protects new region
         }
     }
+
+    makeRegion(regionStart, (BbNode *)nodes.back(), dispatchNode);  // create new try region
+
     MethodDesc* md = compilationInterface.getMethodToCompile();
     md->setNumExceptionHandler(tryRegions.size());
-    
-    IPF_LOG << "    region registration:" << endl;
-    if(tryRegions.size() == 0) {
+    IPF_LOG << endl << "    region registration:" << endl;
+    if (tryRegions.size() == 0) {
         IPF_LOG << "      no catch handlers detected" << endl;
         return;
     }
 
     IPF_LOG << "      start            end              handler          exception                           objIsDead" << endl;
-    for(uint16 i=0; i<tryRegions.size(); i++) {
+    for (uint16 i=0; i<tryRegions.size(); i++) {
         md->setExceptionHandlerInfo(i, 
             tryRegions[i]->startAddr, 
             tryRegions[i]->endAddr,
@@ -170,39 +169,65 @@
 
 //----------------------------------------------------------------------------------------//
 
-void RuntimeSupport::makeRegion(Byte *startAddr, Byte *endAddr, Node *dispatchNode) {
+void RuntimeSupport::makeRegion(BbNode *regionStart, BbNode *regionEnd, Node *dispatchNode) {
 
-    if(dispatchNode == NULL) {
-        IPF_LOG << "      there is no dispatch node - region is not created" << endl;
-        return;
-    }
+    if (dispatchNode == NULL) return;   // it is not a try region
     
-    if(dispatchNode->getNodeKind() != NODE_DISPATCH) return;
+    IPF_LOG << "    try region detected: node" << regionStart->getId() << " - node" << regionEnd->getId();
+
+    if (dispatchNode->getNodeKind() != NODE_DISPATCH) { 
+        IPF_LOG << ", there is no catch block" << endl;
+        return; 
+    }
+
+    IPF_LOG << ", dispatch: node" << dispatchNode->getId();
 
-    IPF_LOG << "      dispatch node is BB" << dispatchNode->getId() << endl;
-    EdgeVector& outEdges = dispatchNode->getOutEdges();      // get out edges   
+    Byte       *startAddr = (Byte *)regionStart->getAddress();
+    Byte       *endAddr   = (Byte *)regionEnd->getAddress();
+    EdgeVector &outEdges  = dispatchNode->getOutEdges();     // get out edges   
     sort(outEdges.begin(), outEdges.end(), greaterPriority); // sort them by Priority
     
-    for(uint16 i=0; i<outEdges.size(); i++) {
-        if(outEdges[i]->getEdgeKind() == EDGE_EXCEPTION) {
-
-            Byte       *handlerAddr   = (Byte *)((BbNode *)outEdges[i]->getTarget())->getAddress();
-            ObjectType *exceptionType = (ObjectType *)((ExceptionEdge *)outEdges[i])->getExceptionType();
+    for (uint16 i=0; i<outEdges.size(); i++) {
+        Edge *edge = outEdges[i];
+        if (edge->getEdgeKind() == EDGE_EXCEPTION) {
+
+            BbNode     *handlerNode   = (BbNode *)edge->getTarget();
+            Byte       *handlerAddr   = (Byte *)handlerNode->getAddress();
+            ObjectType *exceptionType = (ObjectType *)((ExceptionEdge *)edge)->getExceptionType();
             TryRegion  *region = new(mm) TryRegion(startAddr, endAddr, handlerAddr, exceptionType, false);
 
             tryRegions.push_back(region);
-            IPF_LOG << "        region created for handler BB" << outEdges[i]->getTarget()->getId();
-            IPF_LOG << " priority: " << ((ExceptionEdge *)outEdges[i])->getPriority();
-            IPF_LOG << " " << exceptionType->getName() << endl;
+            IPF_LOG << ", handler: node" << handlerNode->getId();
+            IPF_LOG << ", priority: " << ((ExceptionEdge *)edge)->getPriority();
+            IPF_LOG << ", " << exceptionType->getName() << endl;
         }
         
-        if(outEdges[i]->getEdgeKind() == EDGE_DISPATCH) { 
-            makeRegion(startAddr, endAddr, outEdges[i]->getTarget());
+        if (edge->getEdgeKind() == EDGE_DISPATCH) { 
+            makeRegion(regionStart, regionEnd, edge->getTarget());
         }
     }
 }
 
 //----------------------------------------------------------------------------------------//
+
+void RuntimeSupport::inserFakeLastNode(NodeVector &nodes) {
+    
+    BbNode     *lastNode = (BbNode *)nodes.back();
+    InstVector &insts    = lastNode->getInsts();
+    uint64     address   = 0;
+    
+    if (insts.size() < 1) address = lastNode->getAddress();
+    else                  address = lastNode->getInstAddr(insts.back());
+
+    uint64 mask = 0xfffffffffffffff0;
+    address = (address & mask) + 0x10;
+
+    BbNode *node = new(mm) BbNode(mm, 0, 0);
+    node->setAddress(address);
+    nodes.push_back(node);
+}
+
+//----------------------------------------------------------------------------------------//
 // Make info block which will be used in stack unwind routine
 //----------------------------------------------------------------------------------------//
 
@@ -260,17 +285,17 @@
 
 void RuntimeSupport::buildRootSet() {
     
-    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);
-    RegOpndSet liveSet(mm);
+    LiveManager   liveManager(cfg);
+    RegOpndSet    &liveSet = liveManager.getLiveSet();
+    NodeVector    &nodes   = cfg.search(SEARCH_POST_ORDER);
 
     for (uint16 i=0; i<nodes.size(); i++) {              // iterate through CFG nodes
 
         if (nodes[i]->isBb() == false) continue;         // non BB node - ignore
 
-        liveSet.clear();                                 // clear live set
-        nodes[i]->mergeOutLiveSets(liveSet);             // put in the live set merged live sets of successors
+        BbNode *node = (BbNode *)nodes[i];
+        liveManager.init(node);
 
-        BbNode       *node     = (BbNode *)nodes[i];
         InstVector   &insts    = node->getInsts();
         InstIterator currInst  = insts.end()-1;
         InstIterator firstInst = insts.begin()-1;
@@ -278,24 +303,26 @@
         for (; currInst>firstInst; currInst--) {
 
             Inst *inst = *currInst;
-            LiveAnalyzer::defOpnds(liveSet, inst);       // update liveSet for currInst
-            if (Encoder::isBranchCallInst(inst)) {       // if currInst is "call" (only safe point we have)
-                newSafePoint(node, inst, liveSet);       // insert (safe point->liveSet) pair in sp2LiveSet
-            }
-            LiveAnalyzer::useOpnds(liveSet, inst);       // update liveSet for currInst
+            liveManager.def(inst);                       // update liveSet for currInst
+            if (inst->isCall()) {                        // if inst is "call" (only safe point we have)
+                RegOpnd *qp  = (RegOpnd *)inst->getOpnd(0);
+                QpMask  mask = liveManager.getLiveMask(qp);
+                newSafePoint(node, inst, liveSet, mask); // insert (safe point->liveSet) pair in sp2LiveSet
+            }                                            //
+            liveManager.use(inst);                       // update liveSet for currInst
             defMptr(node, inst);                         // build mptr->base dependency for currInst
         }
     }
     
     if (LOG_ON) {
-        IPF_LOG << endl << "    Build mptr to base map" << endl;
+        IPF_LOG << endl << "  Build mptr to base map" << endl;
         for (MptrDefMapIterator it=mptr2def.begin(); it!=mptr2def.end(); it++) {
             IPF_LOG << "      " << IrPrinter::toString(it->first) << "->";
             IPF_LOG << IrPrinter::toString(it->second.base) << endl;
         }
     }
 
-    IPF_LOG << endl << "    Safe point list" << endl;
+    IPF_LOG << endl << "  Safe point list" << endl;
     // set mptr->base relations (vector SafePoint.alivePtrs will contain base after each mptr)
     // and extend bases live ranges
     for (uint16 i=0; i<safePoints.size(); i++) {
@@ -308,13 +335,14 @@
 // - Add new record in rootSet map (sp position -> alive mptrs&bases)
 // - extend base live ranges
  
-void RuntimeSupport::newSafePoint(BbNode *node, Inst *spInst, RegOpndSet &liveSet) {
+void RuntimeSupport::newSafePoint(BbNode *node, Inst *spInst, RegOpndSet &liveSet, QpMask mask) {
     
     safePoints.push_back(SafePoint(mm, node, spInst));  // create record for current safe point
     RegOpndVector &ptrs = safePoints.back().alivePtrs;  // get vector for mptrs and bases alive on the safe point
     
     for (RegOpndSetIterator it=liveSet.begin(); it!=liveSet.end(); it++) {
         RegOpnd *opnd = *it;
+        if (opnd->isAlive(mask) == false) continue;
         if (opnd->getDataKind() == DATA_MPTR) {
             ptrs.push_back(opnd);
             ptrs.push_back(NULL);
@@ -418,7 +446,7 @@
  
 void RuntimeSupport::insertBases(Inst *inst, RegOpndVector &ptrs) {
     
-    IPF_LOG << "      alive pointers:";
+    IPF_LOG << "    alive pointers:";
     for (uint16 i=0; i<ptrs.size(); i++) {
         IPF_LOG << " " << IrPrinter::toString(ptrs[i]);
         if (ptrs[i]->getDataKind() == DATA_MPTR) {
@@ -444,7 +472,7 @@
 
 void RuntimeSupport::makeRootSetInfo(Uint32Vector &info) {
 
-    IPF_LOG << "    Safe points list:" << endl;
+    IPF_LOG << "  Safe points list:" << endl;
     for (uint16 i=0; i<safePoints.size(); i++) {
 
         BbNode *node   = safePoints[i].node;