Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (working copy) @@ -14,14 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ * */ -#include "BitSet.h" #include "IpfCodeLayouter.h" #include "IpfIrPrinter.h" #include "IpfOpndManager.h" @@ -33,7 +32,7 @@ // Compare two edges by prob value //========================================================================================// -bool greaterEdge (Edge *e1, Edge *e2) { return e1->getProb() > e2->getProb(); } +bool greaterEdge(Edge *e1, Edge *e2) { return e1->getProb() > e2->getProb(); } //========================================================================================// // CodeLayouter @@ -50,12 +49,14 @@ IPF_LOG << endl << " Merge Nodes" << endl; mergeNodes(); + checkUnwind(); IPF_LOG << endl << " Make Chains" << endl; makeChains(); + layoutNodes(); - IPF_LOG << endl << " Fix Branches" << endl; - fixBranches(); + IPF_LOG << endl << " Set Branch Targets" << endl; + setBranchTargets(); IPF_STAT << endl << "STAT_NUM_NODES " << cfg.search(SEARCH_POST_ORDER).size() << endl; } @@ -64,269 +65,327 @@ void CodeLayouter::mergeNodes() { - NodeVector& nodes = cfg.search(SEARCH_DIRECT_ORDER); - bool cfgChanged = false; + NodeVector& nodeVector = cfg.search(SEARCH_POST_ORDER); + NodeList nodes(nodeVector.begin(), nodeVector.end()); - for (uint i=0; igetId() << flush; - node->printEdges(LOG_OUT); - } + // try to merge current node with its successor + for (NodeListIterator it=nodes.begin(); it!=nodes.end(); it++) { - // don't merge with enter node - if (cfg.getEnterNode() == nodes[i]) { - IPF_LOG << " - ignore (don't merge with enter node)" << endl; - continue; - } + Node *node = *it; + if (node->getNodeKind() != NODE_BB) continue; // node is not BB - ignore + if (node == cfg.getEnterNode()) continue; // do not merge enter node - // check node has only one successor (not taking in account unwind node) - EdgeVector& outEdges = node->getOutEdges(); - if (outEdges.size() != 1) { - IPF_LOG << " - ignore (has more than one successor)" << endl; - continue; - } + BbNode *pred = (BbNode *)node; // let's name current node "pred" + BbNode *succ = getSucc(pred); // check if it has mergable successor + if (succ == NULL) continue; // current node does not have mergable successor + if (succ == cfg.getExitNode()) continue; // do not merge exit node + if (checkSucc(succ) == false) continue; // succ can not be merged with pred - // check if node is basic block - if (node->getNodeKind() != NODE_BB) { - IPF_LOG << " - ignore (is not basic block)" << endl; - continue; - } - - // don't merge with enter node - if (cfg.getEnterNode() == outEdges[0]->getTarget()) { - IPF_LOG << " - ignore (don't merge with enter node)" << endl; - continue; - } - - // don't merge with enter node - if (outEdges[0]->getTarget()->getNodeKind() != NODE_BB) { - IPF_LOG << " - ignore (target is not basic block)" << endl; - continue; - } - - cfgChanged |= mergeNode((BbNode*)node, outEdges[0]); + merge(pred, succ); // merge pred and succ nodes + nodes.remove(succ); // remove succ node from current nodes list } + cfg.search(SEARCH_UNDEF_ORDER); // we could remove some nodes - old search is broken +} + +//----------------------------------------------------------------------------------------// +// if node has only one succ (not taking in account unwind) - return the succ + +BbNode* CodeLayouter::getSucc(BbNode *node) { - if (cfgChanged) { - cfg.search(SEARCH_UNDEF_ORDER); // we have removed some nodes - old search is broken + Node *succ = NULL; + EdgeVector &outEdges = node->getOutEdges(); + + for (uint16 i=0; igetTarget(); // get successor of current node + if (target->getNodeKind() == NODE_UNWIND) continue; // if it is unwind node - ignore + if (succ != NULL) return NULL; // there is more than one succ - node can not be merged + succ = target; // it is first succ } + + if (succ == NULL) return NULL; // there is no successor + if (succ->getNodeKind() != NODE_BB) return NULL; // if succ is not BB - node can not be merged + return (BbNode *)succ; } + +//----------------------------------------------------------------------------------------// +// check if succ can be merged with pred (has only one pred) + +bool CodeLayouter::checkSucc(BbNode *node) { + + EdgeVector &inEdges = node->getInEdges(); // get succ in edges + if (inEdges.size() > 1) return false; // succ has more than one pred - it can not be merged + return true; +} //----------------------------------------------------------------------------------------// +// merge two nodes -bool CodeLayouter::mergeNode(BbNode *pred, Edge* pred2succ) { - BbNode* succ = (BbNode*)pred2succ->getTarget(); - IPF_LOG << " - try to merge with node" << setw(2) << left; - IPF_LOG << succ->getId() << flush; - if (succ->getNodeKind() != NODE_BB) { // if succ is NODE_DISPATCH - ignore - IPF_LOG << " - succ is not NODE_BB - ignore" << endl; - return false; - } - +void CodeLayouter::merge(BbNode *pred, BbNode *succ) { + + // copy succ's insts in pred node InstVector &predInsts = pred->getInsts(); - if (predInsts.size() != 0) { // checks applicaple to non-empty blocks: - // do not merge non-empty node with exit node - if (succ == cfg.getExitNode()) { - IPF_LOG << " - merge canceled (succ is Exit Node)" << endl; - return false; - } - // if Succ has predecessors other than pred - return - if (succ->getInEdges().size()!=1) { - IPF_LOG << " - succInEdges.size()!=1" << endl; - return false; - } - // insert Succ instructions after Pred instructions - InstVector &succInsts = succ->getInsts(); - for (uint i=0, succsize = succInsts.size(); igetInsts(); + predInsts.insert(predInsts.end(), succInsts.begin(), succInsts.end()); - // remove Pred's out-edge - pred2succ->disconnect(); - // reconnect Pred's in-edges to Succ - EdgeVector &predInEdges = pred->getInEdges(); - while (predInEdges.size()>0) { - predInEdges[predInEdges.size()-1]->connect(succ); + // remove pred out edges + EdgeVector predOutEdges = pred->getOutEdges(); // make copy of pred out edges vector + for (uint16 i=0; iremove(); // remove edge } - // if Pred is enter node - set Succ as new enter node - if (pred == cfg.getEnterNode()) { - cfg.setEnterNode(succ); - IPF_LOG << " - new enter"; + + // redirect succ's out edges on pred + EdgeVector succOutEdges = succ->getOutEdges(); // make copy of succ out edges vector + for (uint16 i=0; ichangeSource(pred); // redirect edge } - IPF_LOG << " - merge successful" << endl; - return true; + IPF_LOG << " node" << left << setw(3) << pred->getId() << " merged with node" << succ->getId() << endl; + + if (LOG_ON) { + if (succ->getInEdges().size() != 0) IPF_ERR << " size " << succ->getInEdges().size() << endl; + if (succ->getOutEdges().size() != 0) IPF_ERR << " size " << succ->getOutEdges().size() << endl; + } } + +//----------------------------------------------------------------------------------------// +// if unwind node does not have predecessors (they could be removed during merging) - it can +// be removed +void CodeLayouter::checkUnwind() { + + // find unwind node (it must be predecessor of exit node) + Node *unwind = NULL; + Node *exit = cfg.getExitNode(); + EdgeVector &inEdges = exit->getInEdges(); // get exit node in edges + for (uint16 i=0; igetSource(); // get edge source + if (unwind->getNodeKind() == NODE_UNWIND) break; // if the source is unwind node - we have found it + } + + // check if unwind can be removed + if (unwind == NULL) return; // there is no unwind node + if (unwind->getInEdges().size() > 0) return; // unwind node is alive - nothind to do + + // remove useless unwind + unwind->remove(); + IPF_LOG << endl << " unwind node removed" << endl; +} + //----------------------------------------------------------------------------------------// void CodeLayouter::makeChains() { - uint maxNodeId=cfg.getMaxNodeId(); - BbNode **availNodes=new(mm) BbNode*[maxNodeId]; - for(uint i=0; igetOutEdges(); // get out edges of current node + edges.insert(edges.end(), outEdges.begin(), outEdges.end()); // add them in edges list } - NodeVector& nodes = cfg.search(SEARCH_DIRECT_ORDER); // actually, order does not matter - for(uint i=0; igetNodeKind() != NODE_BB) continue; // ignore not BB nodes - availNodes[node->getId()] = (BbNode*)node; + // sort edge list by prob + sort(edges.begin(), edges.end(), greaterEdge); + + // make chain list + for (uint16 i=0; igetSource(); + Node *targetNode = edge->getTarget(); + Chain *targetChain = NULL; + Chain *sourceChain = NULL; + + // try to find chains to add current edge in + for (ChainListIterator it=chains.begin(); it!=chains.end(); it++) { + if ((*it)->front() == targetNode) targetChain = *it; + if ((*it)->back() == sourceNode) sourceChain = *it; } - BbNode *currNode = (BbNode*) cfg.getEnterNode(); // start from the Enter Node - uint availPos=0; // where to look for next available node - IPF_LOG << " new chain:"; - for (;;) { - availNodes[currNode->getId()] = NULL; // mark curr node consumed - IPF_LOG << " node" << currNode->getId() << "->"; + if (targetChain!=NULL && sourceChain!=NULL) { // edge connects two existing chains + if (targetChain == sourceChain) return; // do not merge chain with itself + sourceChain->splice(sourceChain->end(), *targetChain); // merge chains in source chain + chains.remove(targetChain); // erase target chain + return; + } + + if (sourceChain != NULL) { // sourceChain ending with edge source + pushBack(sourceChain, targetNode); // push target back in sourceChain + return; + } + + if (targetChain != NULL) { // targetChain starting with edge target + pushFront(targetChain, sourceNode); // push source front in targetChain + return; + } + + // there is no chain that can be merged with the edge + Chain *newChain = new Chain(); // create new chain + pushBack(newChain, sourceNode); // push source back in new chain + pushBack(newChain, targetNode); // push target back in new chain + if (newChain->size() > 0) chains.push_back(newChain); // insert new chain in chain list +} + +//----------------------------------------------------------------------------------------// +// push node in chain end + +void CodeLayouter::pushBack(Chain *chain, Node *node) { + if (visitedNodes.count(node) != 0) return; // node has already been inserted in some chain + visitedNodes.insert(node); // mark node as visited + chain->push_back(node); // push node back in the chain +} + +//----------------------------------------------------------------------------------------// +// push node in chain begining + +void CodeLayouter::pushFront(Chain *chain, Node *node) { + if (visitedNodes.count(node) != 0) return; // node has already been inserted in some chain + visitedNodes.insert(node); // mark node as visited + chain->push_front(node); // push node front in the chain +} + +//----------------------------------------------------------------------------------------// +// set layout successors for BbNodes + +void CodeLayouter::layoutNodes() { + + // sort chains + ChainMap order; + for (ChainListIterator it=chains.begin(); it!=chains.end(); it++) { + uint32 weight = calculateChainWeight(*it); // calculate chain weight + order.insert( make_pair(weight, *it) ); // insert pair weight->chain in map + } + + // set layout successors for BbNodes + BbNode *pred = new(mm) BbNode(0, 0); // current pred node (init with fake node) + BbNode *succ = NULL; // currend succ node + for (ChainMapIterator it1=order.begin(); it1!=order.end(); it1++) { + Chain *chain = it1->second; // current chain + IPF_LOG << " weight: " << setw(10) << it1->first; + IPF_LOG << " chain: " << IrPrinter::toString(*(it1->second)) << endl; - BbNode* nextNode=NULL; - - // find out edge with max prob - double currProb = -10.0; - EdgeVector& outEdges = currNode->getOutEdges(); - for(uint32 j=0; jgetTarget(); - if (availNodes[candidate->getId()] == NULL) continue; // ignore consumed nodes - if (currProb < outEdges[j]->getProb()) { // we have found edge with prob greater then curr - currProb = outEdges[j]->getProb(); // reset curr max prob - nextNode = candidate; // curr cand to be placed in chain - } + for (ChainIterator it2=chain->begin(); it2!=chain->end(); it2++) { + if ((*it2)->isBb() == false) continue; // if current node is not BB - it does not need layouting + succ = (BbNode *)*it2; // + pred->setLayoutSucc(succ); // set current node as layouted successor of pred + pred = succ; // current pred is current node } - if (nextNode==NULL) { - IPF_LOG << endl; // current chain finished - // try to start next chain - for (; availPossetLayoutSucc(nextNode); - currNode=nextNode; } } + //----------------------------------------------------------------------------------------// +// chain weight is exec counters summ of all nodes in the chain -void CodeLayouter::fixBranches() { +uint32 CodeLayouter::calculateChainWeight(Chain *chain) { + + if (chain->front() == cfg.getEnterNode()) return UINT_MAX; // enter node always goes first + uint32 weight = 0; + for (ChainIterator it=chain->begin(); it!=chain->end(); it++) { + if ((*it)->isBb() == false) continue; + BbNode *node = (BbNode *) *it; + weight += node->getExecCounter(); + } + return weight; +} + +//----------------------------------------------------------------------------------------// +// branch targets have not been set yet. In this method we iterate through each node and +// check if it ends with branch (needs branch target) + +void CodeLayouter::setBranchTargets() { + BbNode *node = (BbNode*) cfg.getEnterNode(); - for(; node != NULL; node = node->getLayoutSucc()) { - IPF_LOG << " node" << setw(2) << left << node->getId(); + IPF_LOG << " node" << left << setw(3) << node->getId(); InstVector& insts = node->getInsts(); - // check if last inst is conditional branch if(insts.size() != 0) { - CompVector& compList = insts.back()->getComps(); - if(compList.size()>0 && compList[0] == CMPLT_BTYPE_COND) { - IPF_LOG << " fix conditional branch" << endl; - fixConditionalBranch(node); + Inst *lastInst = insts.back(); + + if (lastInst->isRet()) { + IPF_LOG << " last inst is \"ret\"" << endl; continue; } - } - - // check if last inst is ret - if(insts.size() != 0) { - CompVector& compList = insts.back()->getComps(); - if(compList.size()>0 && compList[0] == CMPLT_BTYPE_RET) { - IPF_LOG << " last inst is \"ret\"" << endl; + + if (lastInst->isConditionalBranch() && lastInst->getComps().size() != 0) { + IPF_LOG << " fix conditional branch:"; + fixConditionalBranch(node); continue; } - } - - // check if last inst is switch - if(insts.size() !=0) { - if(insts.back()->getInstCode() == INST_SWITCH) { + + if(lastInst->getInstCode() == INST_SWITCH) { IPF_LOG << " fix switch" << endl; fixSwitch(node); continue; } } - + // thus, it is unconditional branch - IPF_LOG << " fix unconditional branch" << endl; + IPF_LOG << " fix unconditional branch:"; fixUnconditionalBranch(node); } - cfg.search(SEARCH_UNDEF_ORDER); // it is possible that we have removed some nodes - old search is broken } //----------------------------------------------------------------------------------------// -// (p0) cmp4.ge p8, p0 = r32, r2 -// (p8) br unknown target -// -// Sets branch target accordingly +// set conditional branch target void CodeLayouter::fixConditionalBranch(BbNode *node) { - InstVector& insts = node->getInsts(); - Inst* branchInst = insts.back(); + InstVector &insts = node->getInsts(); + Inst *branchInst = insts.back(); + Edge *branchEdge = node->getOutEdge(EDGE_BRANCH); + Edge *throughEdge = node->getOutEdge(EDGE_THROUGH); - Edge *branchEdge = node->getOutEdge(EDGE_BRANCH); - Edge *throughEdge = node->getOutEdge(EDGE_THROUGH); - - IPF_LOG << " old branch target is node" << branchEdge->getTarget()->getId() << endl; - - // check if branch edge target coinsides with layout successor + // if branch edge target coinsides with layout successor if (branchEdge->getTarget() == node->getLayoutSucc()) { // swap fall through and branch edges throughEdge->setEdgeKind(EDGE_BRANCH); branchEdge->setEdgeKind(EDGE_THROUGH); - Edge *tmpEdge=throughEdge; - throughEdge=branchEdge; branchEdge=tmpEdge; + Edge *tmpEdge = throughEdge; + throughEdge = branchEdge; + branchEdge = tmpEdge; // swap predicate registers of the "cmp" instruction - Inst* cmpInst = *(insts.end() - 2); // get "cmp" inst + Inst* cmpInst = *(insts.end() - 2); // get "cmp" inst (it must stay right before "br") Opnd* p1 = cmpInst->getOpnd(POS_CMP_P1); // get p1 opnd Opnd* p2 = cmpInst->getOpnd(POS_CMP_P2); // get p2 opnd cmpInst->setOpnd(POS_CMP_P1, p2); // set p2 on p1's position cmpInst->setOpnd(POS_CMP_P2, p1); // set p1 on p2's position + + IPF_LOG << " branch retargeted,"; } + BbNode *branchTargetNode = (BbNode *)branchEdge->getTarget(); + BbNode *fallThroughNode = (BbNode *)throughEdge->getTarget(); + BbNode *layoutSuccNode = (BbNode *)node->getLayoutSucc(); + // Set target for branch instruction - NodeRef *targetOpnd = (NodeRef*)branchInst->getOpnd(POS_BR_TARGET); - targetOpnd->setNode((BbNode*)branchEdge->getTarget()); + NodeRef *targetOpnd = (NodeRef *)branchInst->getOpnd(POS_BR_TARGET); + targetOpnd->setNode(branchTargetNode); - IPF_LOG << " new branch target is node" << branchEdge->getTarget()->getId() << endl; + IPF_LOG << " branch target is node" << branchTargetNode->getId() << endl; - // If through edge target coinsides with layout successor - do nothing - BbNode* target=(BbNode*) throughEdge->getTarget(); - if (target == node->getLayoutSucc()) { - IPF_LOG << " through edge coinsides with layout successor" << endl; - return; - } - IPF_LOG << " through edge points to" << target->getId() << endl; + // if fall through node coinsides with layout successor - noting more to do + if (fallThroughNode == layoutSuccNode) return; + + // create new node for unconditional branch on through edge target node + BbNode *branchNode = new(mm) BbNode(cfg.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 - // add intermediate basic block for unconditional branch - BbNode *intNode = new(mm) BbNode(cfg.getNextNodeId(), 0xFFFF); //-1?TBD - IPF_LOG << " generate intermediate node" << intNode->getId() << endl; - intNode->setLayoutSucc(node->getLayoutSucc()); - node->setLayoutSucc(intNode); -// nodes.push_back(intNode); - throughEdge->connect(intNode); - Edge *intEdge = new(mm) Edge(intNode, target, throughEdge->getProb(), EDGE_BRANCH); - cfg.addEdge(intEdge); - cfg.search(SEARCH_UNDEF_ORDER); // old search is broken - - // Add branch instruction - OpndManager* opndManager = cfg.getOpndManager(); - Opnd* p0 = opndManager->getP0(); - NodeRef* targetNodeRef = opndManager->newNodeRef(target); - intNode->addInst(new(mm) Inst(INST_BR, p0, targetNodeRef)); + throughEdge->changeTarget(branchNode); // retarget trough edge on the new node + Edge *edge = new(mm) Edge(branchNode, fallThroughNode, throughEdge->getProb(), EDGE_THROUGH); + edge->insert(); // new edge connects the new node and fall through node + + IPF_LOG << ", through node generated: node" << branchNode->getId() << endl; + cfg.search(SEARCH_UNDEF_ORDER); // old search is broken } //----------------------------------------------------------------------------------------// @@ -336,7 +395,7 @@ Inst* lastInst = node->getInsts().back(); // Find edge corresponding to layout successor and mark it fall through - Edge *throughEdge = node->getOutEdge((Node*) node->getLayoutSucc()); + Edge *throughEdge = node->getOutEdge(node->getLayoutSucc()); throughEdge->setEdgeKind(EDGE_THROUGH); Opnd *troughTargetImm = lastInst->getOpnd(POS_SWITCH_THROUGH); @@ -360,25 +419,27 @@ void CodeLayouter::fixUnconditionalBranch(BbNode *node) { - Edge* throughEdge = node->getOutEdge(EDGE_THROUGH); - if(throughEdge == NULL) { // there is no through edge - nothing to do - IPF_LOG << " there is no through edge" << endl; + // if there is no through edge - do nothing + Edge *throughEdge = node->getOutEdge(EDGE_THROUGH); + if(throughEdge == NULL) { + IPF_LOG << " there is no through edge - ignore" << endl; return; } - // If through edge target coinsides with layout successor - do nothing - BbNode* target=(BbNode*) throughEdge->getTarget(); - if (target == (Node*) node->getLayoutSucc()) { - IPF_LOG << " through edge coinsides with layout successor" << endl; + // if through edge target coinsides with layout successor - do nothing + BbNode *target = (BbNode *)throughEdge->getTarget(); + if (target == node->getLayoutSucc()) { + IPF_LOG << " through edge coinsides with layout successor - ignore" << endl; return; } // Add branch to through edge target - Opnd* p0 = cfg.getOpndManager()->getP0(); - NodeRef* targetNode = cfg.getOpndManager()->newNodeRef(target); - node->addInst(new(mm) Inst(INST_BR, p0, targetNode)); + Opnd *p0 = cfg.getOpndManager()->getP0(); + NodeRef *targetNode = cfg.getOpndManager()->newNodeRef(target); + node->addInst(new(mm) Inst(INST_BR, CMPLT_BTYPE_COND, p0, targetNode)); throughEdge->setEdgeKind(EDGE_BRANCH); + IPF_LOG << " branch on node" << target->getId() << " added" << endl; } } // IPF Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -32,8 +32,8 @@ // Edge //========================================================================================// -Edge::Edge(Node *source_, Node *target_, double prob_) : - edgeKind(EDGE_THROUGH), +Edge::Edge(Node *source_, Node *target_, double prob_, EdgeKind edgeKind_) : + edgeKind(edgeKind_), source(source_), target(target_), prob(prob_) { @@ -41,15 +41,40 @@ //----------------------------------------------------------------------------------------// -Edge::Edge(Node *source_, Node *target_, double prob_, EdgeKind edgeKind_) : - edgeKind(edgeKind_), - source(source_), - target(target_), - prob(prob_) { +void Edge::remove() { + + source->removeEdge(this); + target->removeEdge(this); } //----------------------------------------------------------------------------------------// +void Edge::insert() { + + source->addEdge(this); + target->addEdge(this); +} + +//----------------------------------------------------------------------------------------// + +void Edge::changeSource(Node *source_) { + + source->removeEdge(this); + source = source_; + source->addEdge(this); +} + +//----------------------------------------------------------------------------------------// + +void Edge::changeTarget(Node *target_) { + + target->removeEdge(this); + target = target_; + target->addEdge(this); +} + +//----------------------------------------------------------------------------------------// + bool Edge::isBackEdge() { if(source->getLoopHeader() == target) return true; @@ -85,10 +110,9 @@ double prob_, Type *exceptionType_, uint32 priority_) : - Edge(source_, target_, prob_), + Edge(source_, target_, prob_, EDGE_EXCEPTION), exceptionType(exceptionType_), priority(priority_) { - setEdgeKind(EDGE_EXCEPTION); } //========================================================================================// @@ -105,58 +129,62 @@ void Node::addEdge(Edge *edge) { - if(edge->getSource() == this) outEdges.push_back(edge); - if(edge->getTarget() == this) inEdges.push_back(edge); + if (edge->getSource() == this) outEdges.push_back(edge); + if (edge->getTarget() == this) inEdges.push_back(edge); } //----------------------------------------------------------------------------------------// void Node::removeEdge(Edge *edge) { - if(edge->getSource() == this) remove(outEdges.begin(), outEdges.end(), edge); - if(edge->getTarget() == this) remove(inEdges.begin(), inEdges.end(), edge); + + if (edge->getSource() == this) { + EdgeIterator it = find(outEdges.begin(), outEdges.end(), edge); + if (it != outEdges.end()) outEdges.erase(it); + } + + if (edge->getTarget() == this) { + EdgeIterator it = find(inEdges.begin(), inEdges.end(), edge); + if (it != inEdges.end()) inEdges.erase(it); + } } //----------------------------------------------------------------------------------------// Edge *Node::getOutEdge(EdgeKind edgeKind) { - Edge *edge = NULL; for(uint16 i=0; igetEdgeKind() == edgeKind) { - if(edge != NULL) assert(0); - edge = outEdges[i]; - } + if(outEdges[i]->getEdgeKind() == edgeKind) return outEdges[i]; } - return edge; + return NULL; } //----------------------------------------------------------------------------------------// -Edge *Node::getOutEdge(Node *targetNode) { - for(uint16 i=0; igetTarget() == targetNode) return outEdges[i]; +Edge *Node::getInEdge(EdgeKind edgeKind) { + + for(uint16 i=0; igetEdgeKind() == edgeKind) return inEdges[i]; + } return NULL; } //----------------------------------------------------------------------------------------// -Edge *Node::getInEdge(EdgeKind edgeKind) { - - Edge *edge = NULL; - for(uint16 i=0; igetEdgeKind() == edgeKind) { - if(edge != NULL) assert(0); - edge = inEdges[i]; - } +Edge *Node::getOutEdge(Node *targetNode) { + + for(uint16 i=0; igetTarget() == targetNode) return outEdges[i]; } - return edge; + return NULL; } //----------------------------------------------------------------------------------------// Edge *Node::getInEdge(Node *sourceNode) { - for(uint16 i=0; igetSource() == sourceNode) return inEdges[i]; + } return NULL; } @@ -181,6 +209,21 @@ //----------------------------------------------------------------------------------------// +void Node::remove() { + + EdgeVector edges; + + // remove out edges + edges = outEdges; + for (uint16 i=0; iremove(); + + // remove in edges + edges = inEdges; + for (uint16 i=0; iremove(); +} + +//----------------------------------------------------------------------------------------// + void Node::removeInEdge(Edge *edge) { // remove(inEdges.begin(), inEdges.end(), edge); EdgeVector::iterator last=inEdges.end(); @@ -241,43 +284,17 @@ Cfg::Cfg(MemoryManager &mm, CompilationInterface &compilationInterface): mm(mm), - compilationInterface(compilationInterface), - enterNode(NULL), - lastSearchKind(SEARCH_UNDEF_ORDER), - maxNodeId(0) { + compilationInterface(compilationInterface) { - opndManager = new(mm) OpndManager(mm, compilationInterface); + maxNodeId = 0; + opndManager = new(mm) OpndManager(mm, compilationInterface); + enterNode = NULL; + exitNode = NULL; + lastSearchKind = SEARCH_UNDEF_ORDER; } //----------------------------------------------------------------------------------------// -void Cfg::addEdge(Edge *edge) { - - edge->getSource()->addEdge(edge); - edge->getTarget()->addEdge(edge); -} - -//----------------------------------------------------------------------------------------// - -void Cfg::removeEdge(Edge *edge) { - - edge->getSource()->removeEdge(edge); - edge->getTarget()->removeEdge(edge); -} - -//----------------------------------------------------------------------------------------// - -void Cfg::removeNode(Node *node) { - - EdgeVector &inEdges = node->getInEdges(); - EdgeVector &outEdges = node->getOutEdges(); - - for(uint16 i=0; igetSource()->removeEdge(inEdges[i]); - for(uint16 i=0; igetSource()->removeEdge(outEdges[i]); -} - -//----------------------------------------------------------------------------------------// - NodeVector& Cfg::search(SearchKind searchKind) { if(lastSearchKind == searchKind) return searchResult; @@ -287,11 +304,11 @@ searchResult.clear(); switch(searchKind) { - case SEARCH_DIRECT_ORDER : makeDirectOrdered(exitNode, visitedNodes); break; - case SEARCH_POST_ORDER : makePostOrdered(enterNode, visitedNodes); break; - case SEARCH_LAYOUT_ORDER : makeLayoutOrdered(); break; - case SEARCH_UNDEF_ORDER : break; - default : IPF_LOG << IPF_ERROR << endl; break; + case SEARCH_DIRECT_ORDER : makeDirectOrdered(exitNode, visitedNodes); break; + case SEARCH_POST_ORDER : makePostOrdered(enterNode, visitedNodes); break; + case SEARCH_LAYOUT_ORDER : makeLayoutOrdered(); break; + case SEARCH_UNDEF_ORDER : break; + default : IPF_ERR << endl; break; } return searchResult; Index: working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -30,12 +30,6 @@ namespace IPF { //========================================================================================// -// Typedefs -//========================================================================================// - -typedef vector< NodeVector* > ChainVector; - -//========================================================================================// // CodeLayouter //========================================================================================// @@ -45,17 +39,31 @@ void layout(); protected: + // merge sequential nodes void mergeNodes(); - bool mergeNode(BbNode *pred, Edge *pred2succ); + BbNode* getSucc(BbNode*); + bool checkSucc(BbNode*); + void merge(BbNode*, BbNode*); + void checkUnwind(); + + // layout nodes void makeChains(); - void fixBranches(); - void fixConditionalBranch(BbNode *node); - void fixSwitch(BbNode *node); - void fixUnconditionalBranch(BbNode *node); + void inChainList(Edge*); + void pushBack(Chain*, Node*); + void pushFront(Chain*, Node*); + void layoutNodes(); + uint32 calculateChainWeight(Chain*); + + // set branch targets + void setBranchTargets(); + void fixConditionalBranch(BbNode*); + void fixSwitch(BbNode*); + void fixUnconditionalBranch(BbNode*); MemoryManager &mm; Cfg &cfg; - ChainVector chains; + ChainList chains; + NodeSet visitedNodes; }; } // IPF Index: working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -271,24 +271,27 @@ CompVector &getComps() { return compList; } Completer getComp(uint16 num) { return compList[num]; } void addComp(Completer comp_) { compList.push_back(comp_); } - void removeLastComp() { compList.pop_back(); } void setComp(uint32 num, Completer comp_) { compList[num] = comp_; } void addOpnd(Opnd *opnd_) { opndList.push_back(opnd_); } void removeLastOpnd() { opndList.pop_back(); } - OpndVector &getOpnds() { return opndList; } + OpndVector &getOpnds() { return opndList; } void setOpnd(uint32 num, Opnd *opnd_) { opndList[num] = opnd_; } Opnd *getOpnd(uint32 num) { return opndList[num]; } - char *getInstMnemonic() { return Encoder::getMnemonic(instCode); } - - char *getCompMnemonic(Completer comp) { return Encoder::getMnemonic(comp); } uint16 getNumDst() { return Encoder::getNumDst(instCode); } uint16 getNumOpnd() { return Encoder::getNumOpnd(instCode); } - Inst& set_qp(Opnd *p1) { setOpnd(0, p1); return *this; } + char *getInstMnemonic() { return Encoder::getMnemonic(instCode); } + char *getCompMnemonic(Completer comp) { return Encoder::getMnemonic(comp); } + uint32 getAddr() { return addr; } void setAddr(uint32 addr_) { addr = addr_; } + bool isBr(); + bool isCall(); + bool isRet(); + bool isConditionalBranch(); + protected: InstCode instCode; CompVector compList; @@ -302,16 +305,17 @@ class Edge { public: - Edge(Node *source_, Node *target_, double prob_); Edge(Node *source_, Node *target_, double prob_, EdgeKind kind_); - void setSource(Node *source_) { source = source_; } Node *getSource() { return source; } - void setTarget(Node *target_) { target = target_; } Node *getTarget() { return target; } double getProb() { return prob; } void setProb(double prob_) { prob = prob_; } EdgeKind getEdgeKind() { return edgeKind; } void setEdgeKind(EdgeKind kind_) { edgeKind = kind_; } + void remove(); + void insert(); + void changeSource(Node *source_); + void changeTarget(Node *target_); bool isBackEdge(); void connect(Node *target); void disconnect(); @@ -346,6 +350,7 @@ public: Node(uint32 id_, NodeKind kind_ = NODE_INVALID); + void remove(); void addEdge(Edge *edge); void removeEdge(Edge *edge); Edge *getOutEdge(EdgeKind edgeKind); @@ -355,14 +360,14 @@ Node *getDispatchNode(); void mergeOutLiveSets(RegOpndSet &resultSet); - EdgeVector &getInEdges() { return inEdges; } - EdgeVector &getOutEdges() { return outEdges; } + EdgeVector &getInEdges() { return inEdges; } + EdgeVector &getOutEdges() { return outEdges; } void setNodeKind(NodeKind kind_) { nodeKind = kind_; } NodeKind getNodeKind() { return nodeKind; } void setId(uint32 id_) { id = id_; } uint32 getId() { return id; } void setLiveSet(RegOpndSet& liveSet_) { liveSet = liveSet_; } - RegOpndSet &getLiveSet() { return liveSet; } + RegOpndSet &getLiveSet() { return liveSet; } void clearLiveSet() { liveSet.clear(); } void setLoopHeader(Node *loopHeader_) { loopHeader = loopHeader_; } Node *getLoopHeader() { return loopHeader; } @@ -387,8 +392,7 @@ class BbNode : public Node { public: - BbNode(uint32 execCounter_); - BbNode(uint32 execCounter_, uint32 id_); + BbNode(uint32 id_, uint32 execCounter_); void addInst(Inst *inst); void removeInst(Inst *inst) { insts.erase(find(insts.begin(),insts.end(),inst)); } InstVector &getInsts() { return insts; } @@ -413,38 +417,34 @@ class Cfg { public: - Cfg(MemoryManager &mm, CompilationInterface &compilationInterface); - void addEdge(Edge *edge); - void removeEdge(Edge *edge); - void removeNode(Node *node); - NodeVector &search(SearchKind searchKind); + Cfg(MemoryManager &mm, CompilationInterface &compilationInterface); + NodeVector &search(SearchKind searchKind); - MemoryManager &getMM() { return mm; } - void setEnterNode(Node *enterNode_) { enterNode = enterNode_; } - Node *getEnterNode() { return enterNode; } - void setExitNode(Node *exitNode_) { exitNode = exitNode_; } - Node *getExitNode() { return exitNode; } - OpndManager *getOpndManager() { return opndManager; } - uint16 getNextNodeId() { return maxNodeId++; } - uint16 getMaxNodeId() { return maxNodeId; } - MethodDesc *getMethodDesc() { return compilationInterface.getMethodToCompile(); } - void addArg(Opnd *opnd_) { argList.push_back(opnd_); } - OpndVector &getArgs() { return argList; } + MemoryManager &getMM() { return mm; } + CompilationInterface &getCompilationInterface() { return compilationInterface; } + uint16 getNextNodeId() { return maxNodeId++; } + uint16 getMaxNodeId() { return maxNodeId; } + void setEnterNode(Node *enterNode_) { enterNode = enterNode_; } + void setExitNode(Node *exitNode_) { exitNode = exitNode_; } + Node *getEnterNode() { return enterNode; } + Node *getExitNode() { return exitNode; } + OpndManager *getOpndManager() { return opndManager; } + MethodDesc *getMethodDesc() { return compilationInterface.getMethodToCompile(); } + protected: - void makePostOrdered(Node *node, NodeSet &visitedNodes); - void makeDirectOrdered(Node *node, NodeSet &visitedNodesd); - void makeLayoutOrdered(); + void makePostOrdered(Node *node, NodeSet &visitedNodes); + void makeDirectOrdered(Node *node, NodeSet &visitedNodesd); + void makeLayoutOrdered(); MemoryManager &mm; CompilationInterface &compilationInterface; - Node *enterNode; - Node *exitNode; - NodeVector searchResult; - SearchKind lastSearchKind; - OpndManager *opndManager; - uint16 maxNodeId; - OpndVector argList; + uint16 maxNodeId; + OpndManager *opndManager; + Node *enterNode; + Node *exitNode; + NodeVector searchResult; + SearchKind lastSearchKind; }; } // IPF Index: working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -165,9 +165,9 @@ class EmitterBb { public: EmitterBb(Cfg & cfg_, CompilationInterface & compilationinterface_ - , BbNode * node_, bool _setbreak=false); + , BbNode * node_, bool _break4cafe=false, bool _nop4cafe=false); - BbNode * node; + BbNode * node; InstVector & insts; long isize; vectorbool * stops; @@ -189,8 +189,7 @@ class Emitter { public: - Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_ - , bool break4cafe_=false); + Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_); bool emit(); void printInsts(char *); @@ -228,7 +227,6 @@ MemoryManager& mm; Cfg & cfg; CompilationInterface & compilationinterface; - bool break4cafe; vectorbb * bbs; char * dataoff; long datasize; // full size of data block Index: working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -50,6 +50,7 @@ static string toString(OpndVector&); static string toString(InstVector&); static string toString(InstList&); + static string toString(Chain&); static string toString(NodeKind); static string toString(EdgeKind); static string toString(OpndKind); Index: working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfType.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfType.h (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/include/IpfType.h (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -43,22 +43,6 @@ namespace Jitrino { namespace IPF { -// TODO -#define IpfCOUT std::cerr -extern bool isIpfCompiled(MethodDesc* method); -extern bool isIpfMethod(MethodDesc* method); -extern bool isIpfBreakBb(unsigned int nodeid); -extern bool isIpfBreakMethod(MethodDesc* method, bool recompile=false); -extern bool isIpfLogoutMethod(MethodDesc* method); -extern bool ipfEnableSigillBreakActionHandler; -extern bool ipfEnableAutoSigillBreak; -extern bool ipfSigillBreakAllBB; -extern bool ipfNotifyWhenMethodIsRecompiled; -extern bool ipfCompileAllMethods; -extern int ipfSigillBreakCount; -extern bool ipfLogoutAllMethods; -extern bool __IPF_ONLY__; - //========================================================================================// // Forward declaration //========================================================================================// @@ -120,10 +104,8 @@ #define ROOT_SET_HEADER_SIZE 4 // header size in root set info block #define SAFE_POINT_HEADER_SIZE 12 // header size in safe points info block -//#define LOG_ON ipfLogIsOn // Log for Code Generator is on -//#define VERIFY_ON ipfVerifyIsOn // verification for Code Generator is on -#define LOG_ON 1 // Log for Code Generator is on -#define VERIFY_ON 1 // verification for Code Generator is on +#define LOG_ON ipfLogIsOn // Log for Code Generator is on +#define VERIFY_ON ipfVerifyIsOn // verification for Code Generator is on #define LOG_OUT Log::out() #define STAT_ON 0 // Log for statistic @@ -219,6 +201,8 @@ typedef vector< Edge* > EdgeVector; typedef vector< uint32 > Uint32Vector; typedef list< Inst* > InstList; +typedef list< Node* > NodeList; +typedef list< Edge* > EdgeList; typedef set< Opnd* > OpndSet; typedef set< RegOpnd* > RegOpndSet; typedef set< Node* > NodeSet; @@ -229,12 +213,22 @@ typedef NodeVector::iterator NodeIterator; typedef InstVector::iterator InstIterator; typedef OpndVector::iterator OpndIterator; +typedef EdgeVector::iterator EdgeIterator; typedef OpndSet::iterator OpndSetIterator; typedef RegOpndSet::iterator RegOpndSetIterator; typedef InstList::iterator InstListIterator; +typedef NodeList::iterator NodeListIterator; +typedef EdgeList::iterator EdgeListIterator; typedef Inst2RegOpndSetMap::iterator Inst2RegOpndSetMapIterator; typedef Uint642RegOpndSetMap::iterator Uint642RegOpndSetMapIterator; +typedef NodeList Chain; +typedef list< Chain* > ChainList; +typedef multimap< uint32, Chain*, greater < uint32 > > ChainMap; +typedef Chain::iterator ChainIterator; +typedef ChainList::iterator ChainListIterator; +typedef ChainMap::iterator ChainMapIterator; + //========================================================================================// // IpfType //========================================================================================// Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -70,26 +70,6 @@ namespace Jitrino { namespace IPF { -vector ipfCompileMethodList; -vector ipfNotCompileMethodList; -vector ipfBreakMethodList; -vector ipfBreakBbList; -vector ipfLogoutMethodList; -bool ipfEnableSigillBreakActionHandler = false; -bool ipfEnableAutoSigillBreak = false; -bool ipfSigillBreakAllBB = false; -bool ipfNotifyWhenMethodIsRecompiled = true; -bool ipfCompileAllMethods = true; -int ipfSigillBreakCount = 0; -bool ipfLogoutAllMethods = false; -bool __IPF_ONLY__ = false; - -bool isIpfCompiled(MethodDesc* method) { return false; } -bool isIpfMethod(MethodDesc* method) { return false; } -bool isIpfBreakBb(unsigned int nodeid) { return false; } -bool isIpfBreakMethod(MethodDesc* method, bool recompile) { return false; } -bool isIpfLogoutMethod(MethodDesc* method) { return false; } - //============================================================================// Bundle::Bundle(Cfg& cfg, uint32 itmp, Inst *i0, Inst *i1, Inst *i2) { @@ -256,7 +236,7 @@ //============================================================================// EmitterBb::EmitterBb(Cfg & cfg, CompilationInterface & compilationinterface - , BbNode * node_, bool _setbreak) : + , BbNode * node_, bool _break4cafe, bool _nop4cafe) : node(node_), insts(node->getInsts()) { @@ -272,13 +252,13 @@ consts=new(mm) vectorconst; bsize=0; -// if (__IPF_ONLY__) return; TODO - if (!_setbreak) { - bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); - return; + if (!_break4cafe) { + if (_nop4cafe) { + bundles->addBundle(0x01 + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + } } else { #ifdef SIGILL_BREAK_ACTION_HANDLER if (ipfEnableSigillBreakActionHandler) { @@ -295,22 +275,61 @@ , new(mm) Inst(INST_BREAK, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } else { + if (_nop4cafe) { + bundles->addBundle(0x01 + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + } + } +#else + if (_nop4cafe) { bundles->addBundle(0x01 , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } -#else - bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); #endif } }; //============================================================================// +Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_) : + mm(cfg_.getMM()), + cfg(cfg_), + compilationinterface(compilationinterface_) + { + + removeUselessInst(cfg, compilationinterface); + + (new(mm) IpfVerifier(cfg, compilationinterface))->verifyMethod(); + + bbs = new(mm) vectorbb; + BbNode * node = (BbNode *)cfg.getEnterNode(); + EmitterBb * bbdesc; + bool break4cafe = ipfEnableSigillBreakActionHandler + && (ipfEnableAutoSigillBreak + || isIpfBreakMethod(compilationinterface.getMethodToCompile())); + bool nop4cafe = true; + + do { + // for debugging + // tricking(node->getInsts(), mm, cfg); + + if (isIpfBreakBb(node->getId())) { + bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, true, nop4cafe); + } else { + bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, break4cafe, nop4cafe); + } + bbs->push_back(bbdesc); + if (!ipfSigillBreakAllBB) break4cafe = false; + nop4cafe = false; + } while( (node = node->getLayoutSucc()) != NULL ); + +}; + +//============================================================================// int Emitter::removeUselessInst(Cfg & cfg, CompilationInterface & compilationinterface) { BbNode * node = (BbNode *)cfg.getEnterNode(); int methoduseless = 0; @@ -329,7 +348,7 @@ OpndVector &opnds = inst->getOpnds(); if (opnds[1]->isReg() && opnds[2]->isReg() && opnds[1]->getValue()==opnds[2]->getValue()) { - LOG_OUT << "USELESS: " << IrPrinter::toString(inst) << "\n"; + IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n"; insts.erase(insts.begin() + i); methoduseless++; continue; @@ -342,7 +361,7 @@ OpndVector &opnds = inst->getOpnds(); if (opnds[2]->getValue()==0 && opnds[1]->getValue()==opnds[3]->getValue()) { - LOG_OUT << "USELESS: " << IrPrinter::toString(inst) << "\n"; + IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n"; insts.erase(insts.begin() + i); methoduseless++; continue; @@ -358,55 +377,20 @@ static int alluseless = 0; static int allafter = 0; alluseless += methoduseless; - clog << "USELESS: method: " << methoduseless + IPF_LOG << "USELESS: method: " << methoduseless << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n"; - clog << "USELESS: all: " << alluseless + IPF_LOG << "USELESS: all: " << alluseless << "(" << (((float)alluseless)/(alluseless + allafter)) << "%) instructions\n"; } if (methoduseless > 0) { - LOG_OUT << "USELESS: removed " << methoduseless + IPF_LOG << "USELESS: removed " << methoduseless << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n"; } return methoduseless; } //============================================================================// -Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_ - , bool break4cafe_) : - mm(cfg_.getMM()), - cfg(cfg_), - compilationinterface(compilationinterface_), - break4cafe(break4cafe_) { - - removeUselessInst(cfg, compilationinterface); - - (new(mm) IpfVerifier(cfg, compilationinterface))->verifyMethod(); - - bbs = new(mm) vectorbb; - BbNode * node = (BbNode *)cfg.getEnterNode(); - EmitterBb * bbdesc; - bool setbreak = ipfEnableAutoSigillBreak - || isIpfBreakMethod(compilationinterface.getMethodToCompile()); - - if (break4cafe_) setbreak = true; - - do { - // for debugging - // tricking(node->getInsts(), mm, cfg); - - if (isIpfBreakBb(node->getId())) { - bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, true); - } else { - bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, setbreak); - } - bbs->push_back(bbdesc); - if (!ipfSigillBreakAllBB) setbreak = false; - } while( (node = node->getLayoutSucc()) != NULL ); - -}; - -//============================================================================// InstructionType Emitter::getExecUnitType(int templateindex, int slotindex) { return (InstructionType)((Emitter::BundleDesc[templateindex].slots >> (slotindex * 8)) & 0xFF); } @@ -1167,8 +1151,6 @@ void Emitter::registerDirectCall(Inst * inst, uint64 data) { - if (!ipfNotifyWhenMethodIsRecompiled) return; - InstCode icode = inst->getInstCode(); unsigned int is13 = (icode==INST_BRL13 ? 1 : 0); // must be 1 or 0 Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -89,5 +89,42 @@ if(op6 != NULL) opndList.push_back(op6); } +//----------------------------------------------------------------------------------------// + +bool Inst::isBr() { + if (instCode == INST_BR) return true; + if (instCode == INST_BRL) return true; + if (instCode == INST_BR13) return true; + if (instCode == INST_BRL13) return true; + return false; +} + +//----------------------------------------------------------------------------------------// + +bool Inst::isCall() { + if (isBr() == false) return false; + if (compList.size() == 0) return false; + if (compList[0] == CMPLT_BTYPE_CALL) return true; + return false; +} + +//----------------------------------------------------------------------------------------// + +bool Inst::isRet() { + if (isBr() == false) return false; + if (compList.size() == 0) return false; + if (compList[0] == CMPLT_BTYPE_RET) return true; + return false; +} + +//----------------------------------------------------------------------------------------// + +bool Inst::isConditionalBranch() { + if (isBr() == false) return false; + if (compList.size() == 0) return true; + if (compList[0] == CMPLT_BTYPE_COND) return true; + return false; +} + } // IPF } // Jitrino Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -391,6 +391,19 @@ //----------------------------------------------------------------------------------------// +string IrPrinter::toString(Chain &chain) { + + ostringstream oss; + for(ChainIterator i=chain.begin(); i!=chain.end();) { + oss << "node" << (*i)->getId(); + i++; + if (i!=chain.end()) oss << "->"; + } + return oss.str(); +} + +//----------------------------------------------------------------------------------------// + string IrPrinter::toString(NodeKind nodeKind) { string s; Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -171,7 +171,8 @@ RegOpnd *opnd = opndVector[i]; IPF_LOG << " " << left << setw(5) << IrPrinter::toString(opnd); opndManager->assignLocation(opnd); // assign location for current opnd - IPF_LOG << " after assignment " << IrPrinter::toString(opnd) << endl; + IPF_LOG << " after assignment " << left << setw(5) << IrPrinter::toString(opnd); + IPF_LOG << " spill cost: " << opnd->getSpillCost() << endl; if (opnd->isMem()) continue; // if opnd assigned on stack - nothing more to do Index: working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp (revision 465615) +++ working_vm/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -620,7 +620,7 @@ //---------------------------------------------------------------------------// void IpfCfgVerifier::setDefs() { - OpndVector& args = cfg.getArgs(); + OpndVector args; // = cfg.getArgs(); BitSet* enterIn=getVertex(cfg.getEnterNode())->in; for (uint k=0; ksetBit(args[k]->getId());