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;