Index: vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -32,21 +31,31 @@ // Compare two edges by prob value //========================================================================================// -bool greaterEdge(Edge *e1, Edge *e2) { return e1->getProb() > e2->getProb(); } +bool greaterEdge(Edge *e1, Edge *e2) { + + double c1 = e1->getProb() * e1->getSource()->getExecCounter(); + double c2 = e2->getProb() * e2->getSource()->getExecCounter(); + return c1 > c2; +} //========================================================================================// // CodeLayouter //========================================================================================// -CodeLayouter::CodeLayouter(Cfg &cfg_) : - mm(cfg_.getMM()), - cfg(cfg_) { +CodeLayouter::CodeLayouter(Cfg &cfg) : + mm(cfg.getMM()), + cfg(cfg), + chains(mm), + visitedNodes(mm) { } //----------------------------------------------------------------------------------------// void CodeLayouter::layout() { + IPF_LOG << endl << " Outline predicated direct calls " << endl; + transformPredicatedCalls(); + IPF_LOG << endl << " Merge Nodes" << endl; mergeNodes(); checkUnwind(); @@ -63,10 +72,90 @@ //----------------------------------------------------------------------------------------// +void CodeLayouter::transformPredicatedCalls() { + + Long2Node addr2node(mm); + NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); + for(uint16 i=0; iisBb() == false) continue; // ignore non BB nodes + + BbNode *node = (BbNode *)nodes[i]; + if (node->getInsts().size() == 0) continue; + transformPredicatedCall(node, addr2node); + } + cfg.search(SEARCH_UNDEF_ORDER); +} + +//----------------------------------------------------------------------------------------// + +void CodeLayouter::transformPredicatedCall(BbNode *branchNode, Long2Node &addr2node) { + + Inst *branchInst = branchNode->getInsts().back(); // inst to be branch + Edge *unwindEdge = getUnwindEdge(branchNode); // get edge to unwind node + + if (branchInst->getOpnd(0)->getValue() == 0) return; // if not predicated - ignore + if (branchInst->isCall() == false) return; // if not call - ignore + if (unwindEdge == NULL) return; // if there is no unwind edge - ignore + + uint64 addr = branchInst->getOpnd(3)->getValue(); + OpndVector &opnds = branchInst->getOpnds(); + + BbNode *callNode = NULL; + Inst *callInst = NULL; + Edge *callEdge = NULL; + + 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 + callInst = new(mm) Inst(mm, INST_BRL13, CMPLT_BTYPE_CALL, cfg.getOpndManager()->getP0()); + for (uint16 i=1; iaddOpnd(opnds[i]); + callNode->addInst(callInst); // create and add call instruction + addr2node[addr] = callNode; // the addr is processed, next time we will use this node + unwindEdge->changeSource(callNode); // change unwind edge source + + IPF_LOG << " created new node" << callNode->getId(); + IPF_LOG << " call inst is " << IrPrinter::toString(callInst) << endl; + } else { // call on this addr has been already moved in outstanding node + callNode = addr2node[addr]; // get the node + unwindEdge->remove(); // the node has already had edge on unwind node + IPF_LOG << " use node" << callNode->getId() << endl; + } + + // replace call with branch + for (uint16 i=opnds.size()-1; i>0; i--) opnds.pop_back(); + NodeRef *branchTarget = cfg.getOpndManager()->newNodeRef(); + branchInst->addOpnd(branchTarget); + branchInst->setInstCode(INST_BR); + branchInst->getComps().clear(); + branchInst->addComp(CMPLT_BTYPE_COND); + branchInst->addComp(CMPLT_WH_SPNT); + + // create branch edge + callEdge = new(mm) Edge(branchNode, callNode, 0.001, EDGE_BRANCH); + callEdge->insert(); +} + +//----------------------------------------------------------------------------------------// + +Edge* CodeLayouter::getUnwindEdge(Node *node) { + + Edge *unwindEdge = NULL; + EdgeVector &outEdges = node->getOutEdges(); + for (uint16 i=0; igetTarget(); + if (target->getNodeKind() == NODE_UNWIND) unwindEdge = outEdges[i]; + } + return unwindEdge; +} + +//----------------------------------------------------------------------------------------// + void CodeLayouter::mergeNodes() { NodeVector& nodeVector = cfg.search(SEARCH_POST_ORDER); - NodeList nodes(nodeVector.begin(), nodeVector.end()); + NodeList nodes(mm); + nodes.insert(nodes.begin(), nodeVector.begin(), nodeVector.end()); // try to merge current node with its successor for (NodeListIterator it=nodes.begin(); it!=nodes.end(); it++) { @@ -76,13 +165,22 @@ if (node == cfg.getEnterNode()) continue; // do not merge enter node 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 + BbNode *succ = getCandidate(pred); // check if it has mergable successor + if (succ == NULL) { + IPF_LOG << " node" << left << setw(3) << node->getId() << " does not have mergable successor" << endl; + 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 + + if (isMergable(pred, succ) == false) { + IPF_LOG << " node" << left << setw(3) << node->getId() << " succ can not be merged with pred" << endl; + continue; // succ can not be merged with pred + } merge(pred, succ); // merge pred and succ nodes - nodes.remove(succ); // remove succ node from current nodes list + nodes.remove(pred); // remove pred node from current nodes list + IPF_LOG << " node" << pred->getId() << " removed" << endl; } cfg.search(SEARCH_UNDEF_ORDER); // we could remove some nodes - old search is broken } @@ -90,7 +188,7 @@ //----------------------------------------------------------------------------------------// // if node has only one succ (not taking in account unwind) - return the succ -BbNode* CodeLayouter::getSucc(BbNode *node) { +BbNode* CodeLayouter::getCandidate(BbNode *node) { Node *succ = NULL; EdgeVector &outEdges = node->getOutEdges(); @@ -110,11 +208,17 @@ //----------------------------------------------------------------------------------------// // check if succ can be merged with pred (has only one pred) -bool CodeLayouter::checkSucc(BbNode *node) { +bool CodeLayouter::isMergable(BbNode *pred, BbNode *succ) { - 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; + EdgeVector &outEdges = succ->getOutEdges(); // get out edges of succ + for (uint16 i=0; igetTarget(); // get successor of current succ :) + if (target->getNodeKind() == NODE_DISPATCH) return false; // if it is dispatch node - do not merge + } + + if (pred->getInsts().size() == 0) return true; // empty pred can be merged with any succ + if (succ->getInEdges().size() == 1) return true; // succ has one pred - it can be merged + return false; } //----------------------------------------------------------------------------------------// @@ -125,26 +229,21 @@ // copy succ's insts in pred node InstVector &predInsts = pred->getInsts(); InstVector &succInsts = succ->getInsts(); - predInsts.insert(predInsts.end(), succInsts.begin(), succInsts.end()); + succInsts.insert(succInsts.begin(), predInsts.begin(), predInsts.end()); // remove pred out edges - EdgeVector predOutEdges = pred->getOutEdges(); // make copy of pred out edges vector - for (uint16 i=0; iremove(); // remove edge + EdgeVector &predOutEdges = pred->getOutEdges(); + for (int16 i=predOutEdges.size()-1; i>=0; i--) { // iterate edges + predOutEdges[i]->remove(); // remove edge } - // 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 + // redirect pred in edges on succ + EdgeVector &predInEdges = pred->getInEdges(); + for (int16 i=predInEdges.size()-1; i>=0; i--) { // iterate edges + predInEdges[i]->changeTarget(succ); // redirect edge } - 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; - } + IPF_LOG << " node" << left << setw(3) << pred->getId() << " merged with node" << succ->getId(); } //----------------------------------------------------------------------------------------// @@ -168,6 +267,7 @@ // remove useless unwind unwind->remove(); + cfg.search(SEARCH_UNDEF_ORDER); IPF_LOG << endl << " unwind node removed" << endl; } @@ -176,7 +276,7 @@ void CodeLayouter::makeChains() { // make edge list - EdgeVector edges; + EdgeVector edges(mm); NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); // get nodes vector for (uint16 i=0; igetOutEdges(); // get out edges of current node @@ -224,7 +324,7 @@ } // there is no chain that can be merged with the edge - Chain *newChain = new Chain(); // create new chain + Chain *newChain = new(mm) Chain(mm); // 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 @@ -261,7 +361,7 @@ } // set layout successors for BbNodes - BbNode *pred = new(mm) BbNode(0, 0); // current pred node (init with fake node) + BbNode *pred = new(mm) BbNode(mm, 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 @@ -370,13 +470,14 @@ NodeRef *targetOpnd = (NodeRef *)branchInst->getOpnd(POS_BR_TARGET); targetOpnd->setNode(branchTargetNode); - IPF_LOG << " branch target is node" << branchTargetNode->getId() << endl; + IPF_LOG << " branch target is node" << branchTargetNode->getId(); // if fall through node coinsides with layout successor - noting more to do - if (fallThroughNode == layoutSuccNode) return; + if (fallThroughNode == layoutSuccNode) { IPF_LOG << endl; return; } - // create new node for unconditional branch on through edge target node - BbNode *branchNode = new(mm) BbNode(cfg.getNextNodeId(), fallThroughNode->getExecCounter()); + // 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()); 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 @@ -436,7 +537,7 @@ // Add branch to through edge target Opnd *p0 = cfg.getOpndManager()->getP0(); NodeRef *targetNode = cfg.getOpndManager()->newNodeRef(target); - node->addInst(new(mm) Inst(INST_BR, CMPLT_BTYPE_COND, 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; Index: vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -32,11 +31,11 @@ // Edge //========================================================================================// -Edge::Edge(Node *source_, Node *target_, double prob_, EdgeKind edgeKind_) : - edgeKind(edgeKind_), - source(source_), - target(target_), - prob(prob_) { +Edge::Edge(Node *source, Node *target, double prob, EdgeKind edgeKind) : + edgeKind(edgeKind), + source(source), + target(target), + prob(prob) { } //----------------------------------------------------------------------------------------// @@ -81,48 +80,32 @@ return false; } -//---------------------------------------------------------------------------// -void Edge::connect(Node *target_) { - if (target!=NULL) { -// target->removeEdge(this); - target->removeInEdge(this); - } - target=target_; -// target_->addEdge(this); - target_->addInEdge(this); -} - -//----------------------------------------------------------------------------// -void Edge::disconnect() { - if (target!=NULL) { -// target->removeEdge(this); - target->removeInEdge(this); - target=NULL; - } -} - //========================================================================================// // ExceptionEdge //========================================================================================// -ExceptionEdge::ExceptionEdge(Node *source_, - Node *target_, - double prob_, - Type *exceptionType_, - uint32 priority_) : - Edge(source_, target_, prob_, EDGE_EXCEPTION), - exceptionType(exceptionType_), - priority(priority_) { +ExceptionEdge::ExceptionEdge(Node *source, + Node *target, + double prob, + Type *exceptionType, + uint32 priority) : + Edge(source, target, prob, EDGE_EXCEPTION), + exceptionType(exceptionType), + priority(priority) { } //========================================================================================// // Node //========================================================================================// -Node::Node(uint32 id_, NodeKind kind_) { - id = id_; - nodeKind = kind_; - loopHeader = NULL; +Node::Node(MemoryManager &mm, uint32 id, uint32 execCounter, NodeKind kind) : + id(id), + execCounter(execCounter), + nodeKind(kind), + inEdges(mm), + outEdges(mm), + loopHeader(NULL), + liveSet(mm) { } //----------------------------------------------------------------------------------------// @@ -211,86 +194,35 @@ 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(); + for (int16 i=outEdges.size()-1; i>=0; i--) outEdges[i]->remove(); // remove out edges + for (int16 i=inEdges.size()-1; i>=0; i--) inEdges[i]->remove(); // remove in edges } -//----------------------------------------------------------------------------------------// - -void Node::removeInEdge(Edge *edge) { -// remove(inEdges.begin(), inEdges.end(), edge); - EdgeVector::iterator last=inEdges.end(); - EdgeVector::iterator pos=find(inEdges.begin(), last, edge); - if (pos==last) return; // not found - inEdges.erase(pos); -} - -void Node::addInEdge(Edge *edge) { - inEdges.push_back(edge); -} - -void Node::printEdges(ostream& out, EdgeVector& edges, bool head) { - for (uint i=0; i"; - continue; - } - Node *sibling=head? edge->getTarget(): edge->getSource(); - if (sibling==NULL) { - out << " null"; - continue; - } - out << " " << sibling->getId(); - } -} - -void Node::printEdges(ostream& out) { - out << " ins:"; - printEdges(out, getInEdges(), false); - out << " outs:"; - printEdges(out, getOutEdges(), true); -} - //========================================================================================// // BbNode //========================================================================================// -BbNode::BbNode(uint32 id_, uint32 execCounter_) : - Node(id_, NODE_BB), +BbNode::BbNode(MemoryManager &mm, uint32 id, uint32 execCounter) : + Node(mm, id, execCounter, NODE_BB), + insts(mm), layoutSucc(NULL), - address(0), - execCounter(execCounter_) { + address(0) { } -//----------------------------------------------------------------------------------------// - -void BbNode::addInst(Inst *inst) { - - IPF_LOG << " " << IrPrinter::toString(inst) << endl; - insts.push_back(inst); -} - //========================================================================================// // Cfg //========================================================================================// Cfg::Cfg(MemoryManager &mm, CompilationInterface &compilationInterface): mm(mm), - compilationInterface(compilationInterface) { + compilationInterface(compilationInterface), + maxNodeId(0), + enterNode(NULL), + exitNode(NULL), + searchResult(mm), + lastSearchKind(SEARCH_UNDEF_ORDER) { - maxNodeId = 0; - opndManager = new(mm) OpndManager(mm, compilationInterface); - enterNode = NULL; - exitNode = NULL; - lastSearchKind = SEARCH_UNDEF_ORDER; + opndManager = new(mm) OpndManager(mm, compilationInterface); } //----------------------------------------------------------------------------------------// @@ -300,7 +232,7 @@ if(lastSearchKind == searchKind) return searchResult; lastSearchKind = searchKind; - NodeSet visitedNodes; + NodeSet visitedNodes(mm); searchResult.clear(); switch(searchKind) { Index: vm/jitrino/src/codegenerator/ipf/IpfOpnd.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfOpnd.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfOpnd.cpp (working copy) @@ -14,10 +14,9 @@ * 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,18 +31,18 @@ // Constant //============================================================================// -Constant::Constant(DataKind dataKind_) { - offset = LOCATION_INVALID; - size = 0; - dataKind = dataKind_; +Constant::Constant(DataKind dataKind) : + address(NULL), + offset(LOCATION_INVALID), + size(0), + dataKind(dataKind) { } //============================================================================// // SwitchConstant //============================================================================// -SwitchConstant::SwitchConstant() : Constant(DATA_U64) { -} +SwitchConstant::SwitchConstant(MemoryManager &mm) : Constant(DATA_U64), edgeList(mm) {} //----------------------------------------------------------------------------// @@ -77,44 +76,14 @@ } //============================================================================// -// Float Constants -//============================================================================// - -FloatConstant::FloatConstant(float value_) : Constant(DATA_S) { - value = value_; - setSize(sizeof(float)); -} - -//----------------------------------------------------------------------------// - -void *FloatConstant::getData() { - return NULL; -} - -//============================================================================// -// Double Constants -//============================================================================// - -DoubleConstant::DoubleConstant(double value_) : Constant(DATA_D) { - value = value_; - setSize(sizeof(double)); -} - -//----------------------------------------------------------------------------// - -void *DoubleConstant::getData() { - return NULL; -} - -//============================================================================// // Opnd //============================================================================// -Opnd::Opnd(uint32 id_, OpndKind opndKind_, DataKind dataKind_, int64 value_) : - id(id_), - opndKind(opndKind_), - dataKind(dataKind_), - value(value_) { +Opnd::Opnd(uint32 id, OpndKind opndKind, DataKind dataKind, int64 value) : + id(id), + opndKind(opndKind), + dataKind(dataKind), + value(value) { } //----------------------------------------------------------------------------// @@ -173,11 +142,12 @@ // RegOpnd //============================================================================// -RegOpnd::RegOpnd(uint32 id_, OpndKind opndKind_, DataKind dataKind_, int32 value_) : - Opnd(id_, opndKind_, dataKind_, value_) { - - spillCost = 0; - crossCallSite = false; +RegOpnd::RegOpnd(MemoryManager &mm, uint32 id, OpndKind opndKind, DataKind dataKind, int32 value) : + Opnd(id, opndKind, dataKind, value), + spillCost(0), + depOpnds(mm), + crossCallSite(false), + coalesceCands(mm) { } //----------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/include/IpfCfgVerifier.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCfgVerifier.h (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCfgVerifier.h (working copy) @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -35,8 +34,6 @@ // IpfCfgVerifier //========================================================================================// - extern void ipfCfgVerifier(Cfg& cfg_); - } // IPF } // Jitrino Index: vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -29,20 +28,26 @@ namespace Jitrino { namespace IPF { +typedef StlMap Long2Node; + //========================================================================================// // CodeLayouter //========================================================================================// class CodeLayouter { public: - CodeLayouter(Cfg &cfg_); + CodeLayouter(Cfg&); void layout(); protected: + void transformPredicatedCalls(); + void transformPredicatedCall(BbNode*, Long2Node&); + Edge* getUnwindEdge(Node*); + // merge sequential nodes void mergeNodes(); - BbNode* getSucc(BbNode*); - bool checkSucc(BbNode*); + BbNode* getCandidate(BbNode*); + bool isMergable(BbNode*, BbNode*); void merge(BbNode*, BbNode*); void checkUnwind(); Index: vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -52,7 +51,7 @@ class Constant { public: - Constant(DataKind dataKind_); + Constant(DataKind); void setOffset(int32 offset_) { offset = offset_; } int32 getOffset() { return offset; } void setAddress(void *address_) { address = address_; } @@ -75,7 +74,7 @@ class SwitchConstant : public Constant { public: - SwitchConstant(); + SwitchConstant(MemoryManager&); void addEdge(Edge*); Edge *getEdge(int16 choice) { return edgeList[choice]; }; uint16 getChoice(Edge*); @@ -94,7 +93,7 @@ class Int64Constant : public Constant { public: - Int64Constant(int64 value_) : Constant(DATA_I64) { value = value_; setSize(sizeof(int64)); }; + Int64Constant(int64 value) : Constant(DATA_I64), value(value) { setSize(sizeof(int64)); } void *getData() { return NULL; }; int64 getValue() { return value; }; @@ -108,8 +107,8 @@ class FloatConstant : public Constant { public: - FloatConstant(float value_); - void *getData(); + FloatConstant(float value) : Constant(DATA_S), value(value) { setSize(sizeof(float)); } + void *getData() { return NULL; } double getValue() { return value; }; protected: @@ -122,8 +121,8 @@ class DoubleConstant : public Constant { public: - DoubleConstant(double value_); - void *getData(); + DoubleConstant(double value) : Constant(DATA_D), value(value) { setSize(sizeof(double)); } + void *getData() { return NULL; } double getValue() { return value; }; protected: @@ -152,9 +151,9 @@ bool isWritable(); bool isConstant(); bool isMem(); - - bool isFoldableImm(int16 size) { return isFoldableImm(value, size); } bool isImm(int); + + bool isFoldableImm(int16 size) { return isFoldableImm(value, size); } static bool isFoldableImm(int64 value, int16 size); protected: @@ -170,7 +169,7 @@ class RegOpnd : public Opnd { public: - RegOpnd(uint32, OpndKind, DataKind, int32=LOCATION_INVALID); + RegOpnd(MemoryManager&, uint32, OpndKind, DataKind, int32=LOCATION_INVALID); int64 getValue(); void setLocation(int32 value_) { value = value_; } int32 getLocation() { return value; } @@ -178,20 +177,22 @@ void incSpillCost(uint32 spillCost_) { spillCost += spillCost_; } uint32 getSpillCost() { return spillCost; } RegOpndSet &getDepOpnds() { return depOpnds; } - void markRegBusy(uint16 regNum) { busyRegMask[regNum] = true; } - RegBitSet &getBusyRegMask() { return busyRegMask; } + void insertDepOpnds(RegOpndSet &opnds) { depOpnds.insert(opnds.begin(), opnds.end()); } + void insertDepOpnd(RegOpnd*); void setCrossCallSite(bool crossCallSite_) { crossCallSite = crossCallSite_; } bool getCrossCallSite() { return crossCallSite; } - void insertDepOpnd(RegOpnd *depOpnd); + Int2OpndMap &getCoalesceCands() { return coalesceCands; } + void addCoalesceCand(uint32 execCnt, RegOpnd *opnd) { coalesceCands.insert(make_pair(execCnt, opnd)); } + virtual ~RegOpnd() {} protected: // These fields are for register allocation algorithm uint32 spillCost; // number of opnd uses RegOpndSet depOpnds; // opnds which can not be placed in the same reg with the opnd - RegBitSet busyRegMask; // registers that can not be used for allocation of this opnd bool crossCallSite; // opnd live range crosses call site + Int2OpndMap coalesceCands; // }; //========================================================================================// @@ -200,10 +201,8 @@ class ConstantRef : public Opnd { public: - ConstantRef::ConstantRef(uint32 id_, Constant *constant_, DataKind dataKind_ = DATA_CONST_REF) - : Opnd(id_, OPND_IMM, dataKind_, LOCATION_INVALID) { - constant = constant_; - } + ConstantRef::ConstantRef(uint32 id, Constant *constant, DataKind dataKind = DATA_CONST_REF) : + Opnd(id, OPND_IMM, dataKind, LOCATION_INVALID), constant(constant) {} int64 getValue() { return (int64)constant->getAddress(); } Constant *getConstant() { return constant; } @@ -218,8 +217,8 @@ class NodeRef : public Opnd { public: - NodeRef(uint32 id_, BbNode *node_ = NULL) - : Opnd(id_, OPND_IMM, DATA_NODE_REF, LOCATION_INVALID), node(node_) {} + NodeRef(uint32 id, BbNode *node = NULL) + : Opnd(id, OPND_IMM, DATA_NODE_REF, LOCATION_INVALID), node(node) {} int64 getValue(); void setNode(BbNode *node_) { node = node_; } @@ -229,15 +228,14 @@ BbNode *node; }; - //========================================================================================// // MethodRef //========================================================================================// class MethodRef : public Opnd { public: - MethodRef(uint32 id_, MethodDesc *method_ = NULL) - : Opnd(id_, OPND_IMM, DATA_METHOD_REF, LOCATION_INVALID), method(method_) {} + MethodRef(uint32 id, MethodDesc *method = NULL) + : Opnd(id, OPND_IMM, DATA_METHOD_REF, LOCATION_INVALID), method(method) {} int64 getValue(); void setMethod(MethodDesc *method_) { method = method_; } @@ -253,17 +251,17 @@ class Inst { public: - Inst(InstCode instCode_, - Opnd *op1=NULL, Opnd *op2=NULL, Opnd *op3=NULL, Opnd *op4=NULL, Opnd *op5=NULL, Opnd *op6=NULL); + Inst(MemoryManager&, InstCode, + Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL); - Inst(InstCode instCode_, Completer comp1, - Opnd *op1=NULL, Opnd *op2=NULL, Opnd *op3=NULL, Opnd *op4=NULL, Opnd *op5=NULL, Opnd *op6=NULL); + Inst(MemoryManager&, InstCode, Completer, + Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL); - Inst(InstCode instCode_, Completer comp1, Completer comp2, - Opnd *op1=NULL, Opnd *op2=NULL, Opnd *op3=NULL, Opnd *op4=NULL, Opnd *op5=NULL, Opnd *op6=NULL); + Inst(MemoryManager&, InstCode, Completer, Completer, + Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL); - Inst(InstCode instCode_, Completer comp1, Completer comp2, Completer comp3, - Opnd *op1=NULL, Opnd *op2=NULL, Opnd *op3=NULL, Opnd *op4=NULL, Opnd *op5=NULL, Opnd *op6=NULL); + Inst(MemoryManager&, InstCode, Completer, Completer, Completer, + Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL, Opnd* =NULL); InstCode getInstCode() { return instCode; } void setInstCode(InstCode instCode_) { instCode = instCode_; } @@ -305,7 +303,7 @@ class Edge { public: - Edge(Node *source_, Node *target_, double prob_, EdgeKind kind_); + Edge(Node*, Node*, double, EdgeKind); Node *getSource() { return source; } Node *getTarget() { return target; } double getProb() { return prob; } @@ -317,8 +315,6 @@ void changeSource(Node *source_); void changeTarget(Node *target_); bool isBackEdge(); - void connect(Node *target); - void disconnect(); protected: EdgeKind edgeKind; @@ -348,7 +344,7 @@ class Node { public: - Node(uint32 id_, NodeKind kind_ = NODE_INVALID); + Node(MemoryManager&, uint32, uint32, NodeKind = NODE_INVALID); void remove(); void addEdge(Edge *edge); @@ -360,30 +356,29 @@ Node *getDispatchNode(); void mergeOutLiveSets(RegOpndSet &resultSet); - 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; } - void clearLiveSet() { liveSet.clear(); } - void setLoopHeader(Node *loopHeader_) { loopHeader = loopHeader_; } - Node *getLoopHeader() { return loopHeader; } - bool isBb() { return nodeKind == NODE_BB; } - void addInEdge(Edge *edge); - void removeInEdge(Edge *edge); - void printEdges(ostream& out); + void setExecCounter(uint32 execCounter_) { execCounter = execCounter_; } + uint32 getExecCounter() { return execCounter; } + 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; } + void clearLiveSet() { liveSet.clear(); } + void setLoopHeader(Node *loopHeader_) { loopHeader = loopHeader_; } + Node *getLoopHeader() { return loopHeader; } + bool isBb() { return nodeKind == NODE_BB; } protected: uint32 id; // node unique Id + uint32 execCounter; // profile info (how many times the node executes) NodeKind nodeKind; // EdgeVector inEdges; // in edges list EdgeVector outEdges; // out edges list Node *loopHeader; // header of loop containing this node, if NULL - node is not in loop RegOpndSet liveSet; // set of opnds alive on node enter - void printEdges(ostream& out, EdgeVector& edges, bool head); }; //========================================================================================// @@ -392,23 +387,20 @@ class BbNode : public Node { public: - BbNode(uint32 id_, uint32 execCounter_); - void addInst(Inst *inst); + BbNode(MemoryManager&, uint32, uint32); + void addInst(Inst *inst) { insts.push_back(inst); } void removeInst(Inst *inst) { insts.erase(find(insts.begin(),insts.end(),inst)); } InstVector &getInsts() { return insts; } void setAddress(uint64 address_) { address = address_; } uint64 getAddress() { return address; } void setLayoutSucc(BbNode *layoutSucc_) { layoutSucc = layoutSucc_; } BbNode *getLayoutSucc() { return layoutSucc; } - void setExecCounter(uint32 execCounter_) { execCounter = execCounter_; } - uint32 getExecCounter() { return execCounter; } uint64 getInstAddr(Inst *inst) { return ((uint64)address + inst->getAddr()); } protected: InstVector insts; BbNode *layoutSucc; uint64 address; - uint32 execCounter; }; //========================================================================================// Index: vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCodeSelector.h (working copy) @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -26,7 +25,6 @@ #include "CodeGenIntfc.h" #include "VMInterface.h" -//#include "Profiler.h" #include "IpfCfg.h" #include "IpfOpndManager.h" @@ -48,7 +46,7 @@ void genVars(uint32, VarCodeSelector&); void setMethodDesc(MethodDesc*); void genCFG(uint32, CFGCodeSelector&, bool); -// void setProfileInfo(CodeProfiler*); + void setProfileInfo(CodeProfiler*) {} virtual ~IpfMethodCodeSelector() {} protected: @@ -56,7 +54,6 @@ Cfg &cfg; CompilationInterface &compilationInterface; MethodDesc *methodDesc; -// CodeProfiler *codeProfiler; OpndVector opnds; NodeVector nodes; }; @@ -111,9 +108,6 @@ //========================================================================================// // IpfInstCodeSelector //========================================================================================// -//Jitrino::CG_OpndHandle* Jitrino::InstructionCallback::scaledDiffRef(Jitrino::CG_OpndHandle*, Jitrino::CG_OpndHandle*) -//virtual Jitrino::CG_OpndHandle* Jitrino::InstructionCallback::tau_ldIntfTableAddr(Jitrino::Type*, Jitrino::CG_OpndHandle*, Jitrino::NamedType*) -//virtual Jitrino::CG_OpndHandle* Jitrino::InstructionCallback::callvmhelper(unsigned int, Jitrino::CG_OpndHandle**, Jitrino::Type*, Jitrino::VMHelperCallOp::Id, Jitrino::InlineInfo*) class IpfInstCodeSelector : public InstructionCallback { @@ -213,7 +207,7 @@ CG_OpndHandle *tau_ldVirtFunAddr(Type*, CG_OpndHandle*, MethodDesc*, CG_OpndHandle*); CG_OpndHandle *tau_ldVTableAddr(Type*, CG_OpndHandle*, CG_OpndHandle*); CG_OpndHandle *getVTableAddr(Type*, ObjectType*); - CG_OpndHandle *tau_ldIntfTableAddr(Type*, CG_OpndHandle*, NamedType*); + CG_OpndHandle *tau_ldIntfTableAddr(Type*, CG_OpndHandle*, NamedType*, CG_OpndHandle*); CG_OpndHandle *ldFieldAddr(Type*, CG_OpndHandle*, FieldDesc*); CG_OpndHandle *ldStaticAddr(Type*, FieldDesc*); @@ -223,7 +217,7 @@ CG_OpndHandle *newArray(ArrayType*, CG_OpndHandle*); CG_OpndHandle *newMultiArray(ArrayType*, uint32, CG_OpndHandle**); CG_OpndHandle *ldElemBaseAddr(CG_OpndHandle*); - CG_OpndHandle *addElemIndex(Type*, CG_OpndHandle*, CG_OpndHandle*); + CG_OpndHandle *addElemIndex(Type *, CG_OpndHandle *, CG_OpndHandle *); CG_OpndHandle *tau_arrayLen(Type*, ArrayType*, Type*, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*); //---------------------------------------------------------------------------// @@ -304,7 +298,7 @@ void tau_stField(CG_OpndHandle*, CG_OpndHandle*, Type::Tag, FieldDesc*, bool, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_V("tau_stField") } void tau_stElem(CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*, bool, CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_V("tau_stElem") } void optimisticBalancedMonitorExit(CG_OpndHandle*, CG_OpndHandle*, CG_OpndHandle*) { NOT_IMPLEMENTED_V("optimisticBalancedMonitorExit") } - CG_OpndHandle *callvmhelper(uint32, CG_OpndHandle**, Type*, VMHelperCallOp::Id, InlineInfo* = NULL) { NOT_IMPLEMENTED_C("callvmhelper") } + CG_OpndHandle *callvmhelper(uint32, CG_OpndHandle**, Type *, VMHelperCallOp::Id) { NOT_IMPLEMENTED_C("callvmhelper") } //---------------------------------------------------------------------------// // convertors from HLO to IPF::CG types @@ -329,6 +323,7 @@ protected: // Create new inst and add it in current node + void addInst(Inst* inst); Inst& addNewInst(InstCode instCode_, CG_OpndHandle *op1=NULL, CG_OpndHandle *op2=NULL, CG_OpndHandle *op3=NULL, CG_OpndHandle *op4=NULL, CG_OpndHandle *op5=NULL, CG_OpndHandle *op6=NULL); @@ -338,10 +333,13 @@ Inst& addNewInst(InstCode instCode_, Completer comp1, Completer comp2, CG_OpndHandle *op1=NULL, CG_OpndHandle *op2=NULL, CG_OpndHandle *op3=NULL, CG_OpndHandle *op4=NULL, CG_OpndHandle *op5=NULL, CG_OpndHandle *op6=NULL); + Inst& addNewInst(InstCode instCode_, Completer comp1, Completer comp2, Completer comp3, + CG_OpndHandle *op1=NULL, CG_OpndHandle *op2=NULL, CG_OpndHandle *op3=NULL, + CG_OpndHandle *op4=NULL, CG_OpndHandle *op5=NULL, CG_OpndHandle *op6=NULL); // CG helper methods - void directCall(uint32, Opnd**, RegOpnd*, Opnd*, RegOpnd*); - void indirectCall(uint32, Opnd**, RegOpnd*, RegOpnd*, RegOpnd*); + void directCall(uint32, Opnd**, RegOpnd*, Opnd*, RegOpnd*, Completer=CMPLT_WH_SPTK); + void indirectCall(uint32, Opnd**, RegOpnd*, RegOpnd*, RegOpnd*, Completer=CMPLT_WH_SPTK); void makeCallArgs(uint32, Opnd**, Inst*, RegOpnd*); RegOpnd *makeConvOpnd(RegOpnd*); void makeRetVal(RegOpnd*, RegOpnd*, RegOpnd*); Index: vm/jitrino/src/codegenerator/ipf/include/IpfCodeGenerator.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCodeGenerator.h (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCodeGenerator.h (working copy) @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -38,7 +37,7 @@ public: CodeGenerator(MemoryManager&, CompilationInterface&); bool genCode(MethodCodeSelector&); - void genCode(SessionAction* s, MethodCodeSelector& m) {} // TODO +// void genCode(SessionAction* s, MethodCodeSelector& m) {} // TODO virtual ~CodeGenerator() {} protected: Index: vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfCodeSelector.cpp (working copy) @@ -14,10 +14,9 @@ * 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,14 +31,14 @@ // IpfMethodCodeSelector //========================================================================================// -IpfMethodCodeSelector::IpfMethodCodeSelector(Cfg &cfg_, - CompilationInterface &compilationInterface_) : - mm(cfg_.getMM()), - cfg(cfg_), - compilationInterface(compilationInterface_) { - - methodDesc = NULL; -// codeProfiler = NULL; +IpfMethodCodeSelector::IpfMethodCodeSelector(Cfg &cfg, + CompilationInterface &compilationInterface) : + mm(cfg.getMM()), + cfg(cfg), + compilationInterface(compilationInterface), + methodDesc(NULL), + opnds(mm), + nodes(mm) { } //----------------------------------------------------------------------------------------// @@ -70,22 +69,16 @@ //----------------------------------------------------------------------------------------// -//void IpfMethodCodeSelector::setProfileInfo(CodeProfiler *codeProfiler_) { -// codeProfiler = codeProfiler_; -//} - -//----------------------------------------------------------------------------------------// - MethodDesc *IpfMethodCodeSelector::getMethodDesc() { return methodDesc; } //========================================================================================// // IpfVarCodeSelector //========================================================================================// -IpfVarCodeSelector::IpfVarCodeSelector(Cfg &cfg_, OpndVector &opnds_) : - mm(cfg_.getMM()), - cfg(cfg_), - opnds(opnds_) { +IpfVarCodeSelector::IpfVarCodeSelector(Cfg &cfg, OpndVector &opnds) : + mm(cfg.getMM()), + cfg(cfg), + opnds(opnds) { opndManager = cfg.getOpndManager(); } @@ -119,15 +112,15 @@ // IpfCfgCodeSelector //========================================================================================// -IpfCfgCodeSelector::IpfCfgCodeSelector(Cfg &cfg_, - NodeVector &nodes_, - OpndVector &opnds_, - CompilationInterface &compilationInterface_) : - mm(cfg_.getMM()), - cfg(cfg_), - nodes(nodes_), - opnds(opnds_), - compilationInterface(compilationInterface_) { +IpfCfgCodeSelector::IpfCfgCodeSelector(Cfg &cfg, + NodeVector &nodes, + OpndVector &opnds, + CompilationInterface &compilationInterface) : + mm(cfg.getMM()), + cfg(cfg), + nodes(nodes), + opnds(opnds), + compilationInterface(compilationInterface) { } //----------------------------------------------------------------------------------------// @@ -136,7 +129,7 @@ uint32 numOutEdges, double cnt) { - Node *node = new(mm) Node(cfg.getNextNodeId(), NODE_DISPATCH); + Node *node = new(mm) Node(mm, cfg.getNextNodeId(), (uint32) cnt, NODE_DISPATCH); nodes.push_back(node); IPF_LOG << endl << " Generate Dispatch node" << node->getId() << endl; @@ -145,13 +138,13 @@ //----------------------------------------------------------------------------------------// -uint32 IpfCfgCodeSelector::genBlock(uint32 numInEdges, - uint32 numOutEdges, - BlockKind blockKind, - BlockCodeSelector& codeSelector, - double cnt) { +uint32 IpfCfgCodeSelector::genBlock(uint32 numInEdges, + uint32 numOutEdges, + BlockKind blockKind, + BlockCodeSelector &codeSelector, + double cnt) { - BbNode *node = new(mm) BbNode(cfg.getNextNodeId(), (uint32)cnt); + BbNode *node = new(mm) BbNode(mm, cfg.getNextNodeId(), (uint32)cnt); nodes.push_back(node); if(blockKind == Prolog) cfg.setEnterNode(node); @@ -169,7 +162,7 @@ uint32 numOutEdges, double cnt) { - Node *node = new(mm) Node(cfg.getNextNodeId(), NODE_UNWIND); + Node *node = new(mm) Node(mm, cfg.getNextNodeId(), (uint32) cnt, NODE_UNWIND); nodes.push_back(node); IPF_LOG << endl << " Generate Unwind node" << node->getId() << endl; @@ -180,7 +173,7 @@ uint32 IpfCfgCodeSelector::genExitNode(uint32 numInEdges, double cnt) { - BbNode *node = new(mm) BbNode(cfg.getNextNodeId(), (uint32) cnt); + BbNode *node = new(mm) BbNode(mm, cfg.getNextNodeId(), (uint32) cnt); nodes.push_back(node); cfg.setExitNode(node); @@ -198,7 +191,7 @@ IPF_LOG << " -> node" << nodes[headNodeId]->getId() << endl; Edge *edge = new(mm) Edge(nodes[tailNodeId], nodes[headNodeId], prob, EDGE_THROUGH); - cfg.addEdge(edge); + edge->insert(); } //----------------------------------------------------------------------------------------// @@ -209,7 +202,7 @@ IPF_LOG << " -> node" << nodes[headNodeId]->getId() << endl; Edge *edge = new(mm) Edge(nodes[tailNodeId], nodes[headNodeId], prob, EDGE_BRANCH); - cfg.addEdge(edge); + edge->insert(); } //----------------------------------------------------------------------------------------// @@ -220,7 +213,7 @@ IPF_LOG << " -> node" << nodes[headNodeId]->getId() << endl; Edge *edge = new(mm) Edge(nodes[tailNodeId], nodes[headNodeId], prob, EDGE_THROUGH); - cfg.addEdge(edge); + edge->insert(); } //----------------------------------------------------------------------------------------// @@ -247,7 +240,7 @@ << "; defaultTarget=" << defaultTarget << endl; defedge = new(mm) Edge(nodes[tailNodeId], nodes[defaultTarget], probs[defaultTarget], EDGE_BRANCH); - cfg.addEdge(defedge); + defedge->insert(); for(i=0; iinsert(); switchConstant->addEdge(edge); - cfg.addEdge(edge); } if (!defadded) { @@ -282,7 +275,8 @@ IPF_LOG << " Generate Exception edge node" << tailNodeId; IPF_LOG << " -> node" << headNodeId << endl; - cfg.addEdge(new(mm) Edge(tailNode, headNode, prob, EDGE_DISPATCH)); + Edge *edge = new(mm) Edge(tailNode, headNode, prob, EDGE_DISPATCH); + edge->insert(); } //----------------------------------------------------------------------------------------// @@ -300,7 +294,7 @@ IPF_LOG << " -> node" << headNode->getId() << endl; ExceptionEdge *edge = new(mm) ExceptionEdge(tailNode, headNode, prob, exceptionType, priority); - cfg.addEdge(edge); + edge->insert(); } //----------------------------------------------------------------------------------------// @@ -316,7 +310,7 @@ IPF_LOG << " -> node" << headNode->getId() << endl; Edge *edge = new(mm) Edge(tailNode, headNode, prob, EDGE_THROUGH); - cfg.addEdge(edge); + edge->insert(); } //----------------------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp (working copy) @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -34,6 +33,7 @@ #include "IpfPrologEpilogGenerator.h" #include "IpfRuntimeSupport.h" #include "IpfCfgVerifier.h" +#include "IpfInstrumentator.h" namespace Jitrino { namespace IPF { @@ -56,14 +56,13 @@ MemoryManager mm(0x1000, "IpfCodeGenerator"); cfg = new(mm) Cfg(mm, compilationInterface); - char logDirName[] = "tmp_dir_name"; - IrPrinter irPrinter(*cfg, logDirName); + IrPrinter irPrinter(*cfg, (char *)Log::getLogDirName()); methodDesc = compilationInterface.getMethodToCompile(); -// bool ipfLogIsOnSaved = ipfLogIsOn; -// if (isIpfLogoutMethod(methodDesc)) { -// ipfLogIsOn = true; -// } + bool ipfLogIsOnSaved = ipfLogIsOn; + if (isIpfLogoutMethod(methodDesc)) { + ipfLogIsOn = true; + } if(LOG_ON) { const char *methodName = methodDesc->getName(); const char *methodTypeName = (methodDesc->getParentType()!=NULL @@ -81,15 +80,17 @@ methodDesc = ipfMethodCodeSelector.getMethodDesc(); cfg->getOpndManager()->initCompBases((BbNode *)cfg->getEnterNode()); cfg->getOpndManager()->saveThisArg(); - if(LOG_ON) irPrinter.printCfgDot("/cfg_cs.dot"); + if(LOG_ON) irPrinter.printCfgDot("/cs.dot"); + 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("/cfg_cl.dot"); - irPrinter.printLayoutDot("/lot.dot"); - } + if(LOG_ON) irPrinter.printCfgDot("/cl.dot"); + if(LOG_ON) irPrinter.printAsm(LOG_OUT); IPF_LOG << endl << "=========== Stage: Liveness analyzis =========================" << endl; LiveAnalyzer liveAnalyzer(*cfg); @@ -98,8 +99,8 @@ IPF_LOG << endl << "=========== Stage: Dead Code Eliminator ======================" << endl; Dce dce(*cfg); dce.eliminate(); + liveAnalyzer.makeLiveSets(false); - liveAnalyzer.makeLiveSets(false); IPF_LOG << endl << "=========== Stage: Build GC Root Set =========================" << endl; RuntimeSupport runtimeSupport(*cfg, compilationInterface); runtimeSupport.buildRootSet(); @@ -128,7 +129,7 @@ if(ret) IPF_LOG << endl << "=========== Compilation Successful ===========================" << endl; else IPF_LOG << endl << "=========== Compilation Failed ===============================" << endl; -// ipfLogIsOn = ipfLogIsOnSaved; + ipfLogIsOn = ipfLogIsOnSaved; return ret; } Index: vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp (revision 472423) +++ vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp (working copy) @@ -17,753 +17,12 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ -#include "BitSet.h" -#include "IpfCfgVerifier.h" -#include "IpfOpndManager.h" -#include "IpfIrPrinter.h" namespace Jitrino { namespace IPF { -//========================================================================================// -// OrderededNodeVector -//========================================================================================// -class OrderededNodeVector:public NodeVector { - friend class CfgView; -public: - OrderededNodeVector(Cfg& cfg_, const char* orderName, bool fromEnter=true): - cfg(cfg_), - orderName(orderName), - valid(false), - fromEnter(fromEnter), - nodes(*this), - visitedNodes(cfg_.getMM(), cfg_.getMaxNodeId()) - {} - - void collect(); - void printContent(ostream& out); - -protected: - - virtual void makeOrdered(Node* node)=0; - virtual ~OrderededNodeVector(){}; // for gcc - - Cfg& cfg; - const char* orderName; - bool valid; - bool fromEnter; - NodeVector& nodes; - BitSet visitedNodes; - -}; - -//---------------------------------------------------------------------------// -void OrderededNodeVector::collect() { - if (valid) return; - nodes.clear(); - uint32 numNodes=cfg.getMaxNodeId(); - visitedNodes.resizeClear(numNodes); - makeOrdered(fromEnter?cfg.getEnterNode():cfg.getExitNode()); - valid=true; -} - -//---------------------------------------------------------------------------// -void OrderededNodeVector::printContent(ostream& out) { - out << "CFG ordered: " << orderName << " size:" << size() << endl; - for(uint k=0; kgetId() << ": "; - node->printEdges(out); - out << endl; - } -} - -//---------------------------------------------------------------------------// -class DirectOrderedNodeVector: public OrderededNodeVector { -public: - DirectOrderedNodeVector(Cfg& cfg_): - OrderededNodeVector(cfg_, "Direct", false) - {} -protected: - virtual void makeOrdered(Node* node); - -}; - -void DirectOrderedNodeVector::makeOrdered(Node* node) { - visitedNodes.setBit(node->getId()); // mark node visited - EdgeVector& inEdges = node->getInEdges(); // get inEdges - for (uint i=0; igetSource(); // get pred node - if (pred==NULL) { - assert(pred); - continue; - } - if (visitedNodes.getBit(pred->getId())) continue; // if it is already visited - ignore - makeOrdered(pred); // we have found unvisited pred - reenter - } - nodes.push_back(node); // all succs have been visited - place node in searchResult vector -} - -//----------------------------------------------------------------------------------------// -class PostOrderededNodeVector: public OrderededNodeVector { -public: - PostOrderededNodeVector(Cfg& cfg_): - OrderededNodeVector(cfg_, "Post") - {} -protected: - virtual void makeOrdered(Node* node); - -}; - -void PostOrderededNodeVector::makeOrdered(Node* node) { - visitedNodes.setBit(node->getId()); // mark node visited - EdgeVector& outEdges = node->getOutEdges(); // get outEdges - for (uint i=0; igetTarget(); // get succ node - if (succ==NULL) { - assert(succ); - continue; - } - if (visitedNodes.getBit(succ->getId())) continue; // if it is already visited - ignore - makeOrdered(succ); // we have found unvisited succ - reenter - } - nodes.push_back(node); // all succs have been visited - place node in searchResult vector -} - -//----------------------------------------------------------------------------------------// - -class LayoutOrderedNodeVector: public OrderededNodeVector { -public: - LayoutOrderedNodeVector(Cfg& cfg_): - OrderededNodeVector(cfg_, "Layout") - {} -protected: - virtual void makeOrdered(Node* node); - -}; - -void LayoutOrderedNodeVector::makeOrdered(Node* node_) { - BbNode* node = (BbNode*)node_; - while (node != NULL) { - visitedNodes.setBit(node->getId()); // mark node visited - nodes.push_back(node); - node = node->getLayoutSucc(); - } -} - -//========================================================================================// -class CfgView { -public: - CfgView(Cfg& cfg_): - directOrderedNodes(cfg_), - postOrderedNodes(cfg_), - layoutOrderedNodes(cfg_) - {} - - OrderededNodeVector& sortNodes(SearchKind searchKind); - void changed(); - bool verifyNodes(ostream& cout); - -private: - DirectOrderedNodeVector directOrderedNodes; - PostOrderededNodeVector postOrderedNodes; - LayoutOrderedNodeVector layoutOrderedNodes; -}; - -//---------------------------------------------------------------------------// -OrderededNodeVector& CfgView::sortNodes(SearchKind searchKind) { - switch (searchKind) { - case SEARCH_DIRECT_ORDER : - directOrderedNodes.collect(); - return directOrderedNodes; - case SEARCH_POST_ORDER : - postOrderedNodes.collect(); - return postOrderedNodes; - case SEARCH_LAYOUT_ORDER : - layoutOrderedNodes.collect(); - return layoutOrderedNodes; - case SEARCH_UNDEF_ORDER : - if (directOrderedNodes.valid) return directOrderedNodes; - if (postOrderedNodes.valid) return postOrderedNodes; - layoutOrderedNodes.collect(); - return layoutOrderedNodes; - default: - IPF_LOG << IPF_ERROR << endl; - assert(0); - layoutOrderedNodes.collect(); - return layoutOrderedNodes; - } -} - -bool CfgView::verifyNodes(ostream& cout) { - OrderededNodeVector& dir=sortNodes(SEARCH_DIRECT_ORDER); - OrderededNodeVector& post=sortNodes(SEARCH_POST_ORDER); - if (dir.visitedNodes.isEqual(post.visitedNodes)) return true; - cout << "verifyNodes: DIRECT_ORDER and POST_ORDER differs:" << endl; - BitSet collectedNodes(dir.visitedNodes); - collectedNodes.subtract(post.visitedNodes); - if (!collectedNodes.isEmpty()) { - cout << " DIRECT-POST = "; - collectedNodes.print(cout); - } - collectedNodes.copyFrom(post.visitedNodes); - collectedNodes.subtract(dir.visitedNodes); - if (!collectedNodes.isEmpty()) { - cout << " POST-DIRECT = "; - collectedNodes.print(cout); - } -// IPF_EXIT("CfgView::verifyNodes"); - return false; -} - -void CfgView::changed() { - directOrderedNodes.valid=false; - postOrderedNodes.valid=false; - layoutOrderedNodes.valid=false; -} - -//===========================================================================// -class IpfCfgVerifier: public CfgView { - friend class Vertex; - friend class VertexBB; -protected: - MemoryManager& mm; - Cfg& cfg; - uint numAllNodes; - uint numNodes; - uint numOpnds; - NodeVector& nodes; - Vertex** verticesById; // by node ids - Vertex** vertices; // post-ordered - BitSet tmpSet; - BitSet tmpSet2; - BitSet ignoredOpnds; - RegOpnd** opndsById; - uint p0Id; - - Vertex* getVertex(Node* node) { - return verticesById[node->getId()]; - } - VertexBB* getVertexBB(BbNode* node) { - return (VertexBB*)(verticesById[node->getId()]); - } - Vertex* getSourceVertex(Edge* edge) { - return getVertex(edge->getSource()); - } - Vertex* getTargetVertex(Edge* edge) { - return getVertex(edge->getTarget()); - } - - void registerOpnds(OpndVector& opnds); - void printOpndSet(ostream& os, const char* str, BitSet& set); -public: - - IpfCfgVerifier(MemoryManager& mm, Cfg& cfg); - void setDefUse(); - bool collectLiveSets(); - virtual bool checkLiveSets(); - - void setDefs(); - bool collectDefs(); - virtual bool checkDefs(); - - virtual ~IpfCfgVerifier() {} -}; // end class IpfCfgVerifier - -struct Vertex { -// friend class IpfCfgVerifier; - IpfCfgVerifier& fSolver; - Node* node; - BitSet* in; - BitSet* out; - - Vertex(MemoryManager& mm, IpfCfgVerifier& fSolver, Node* node, int width): - fSolver(fSolver), - node(node), - in(new(mm) BitSet(mm, width)), - out(in) - {} - - EdgeVector& getInEdges() { - return node->getInEdges(); - } - EdgeVector& getOutEdges() { - return node->getOutEdges(); - } - - virtual void computeIn(); -// virtual bool checkLiveSet() {return true; } - bool checkLiveSet(); - - virtual void computeOut(); - virtual bool checkDefs() {return true; } - -}; - -struct VertexBB:Vertex { -// friend class IpfCfgVerifier; - BbNode* node; - BitSet* use; - BitSet* def; - - VertexBB(MemoryManager& mm, IpfCfgVerifier& fSolver, BbNode* node, int width): - Vertex(mm, fSolver, node, width), - node(node), - use(new(mm) BitSet(mm, width)), - def(new(mm) BitSet(mm, width)) // TODO: def and use may be null - { - in=new(mm) BitSet(mm, width); - } - - void setDefUse(); - virtual void computeIn(); -// virtual bool checkLiveSet(); - - void setDef(Inst* inst); - void setDef(); - virtual void computeOut(); - bool checkOpndIsDef(Opnd* opnd, uint instId); - virtual bool checkDefs(); - -}; - -//---------------------------------------------------------------------------// -IpfCfgVerifier::IpfCfgVerifier(MemoryManager& mm, Cfg& cfg): - CfgView(cfg), - mm(mm), - cfg(cfg), - numAllNodes(cfg.getMaxNodeId()), - numOpnds(cfg.getOpndManager()->getNumOpnds()), - nodes(sortNodes(SEARCH_DIRECT_ORDER)), - verticesById(new(mm) (Vertex*)[numAllNodes]), - vertices(NULL), - tmpSet(mm, numOpnds), - tmpSet2(mm, numOpnds), - ignoredOpnds(mm, numOpnds), - opndsById(new(mm) (RegOpnd*)[numOpnds]), - p0Id(cfg.getOpndManager()->getP0()->getId()) -{ - for (uint k=0; kgetNodeKind()==NODE_BB) { - vertex=new(mm) VertexBB(mm, *this, (BbNode*)node, numOpnds); - } else { - vertex=new(mm) Vertex(mm, *this, node, numOpnds); - } - verticesById[node->getId()]=vertex; - vertices[k]=vertex; - } -} - -//---------------------------------------------------------------------------// -void IpfCfgVerifier::printOpndSet(ostream& os, const char* str, BitSet& set) { - RegOpndSet opndSet; - os << str; - for (uint k=0; kisReg()) continue; - RegOpnd* reg = (RegOpnd*)opnd; - uint id=opnd->getId(); - if (opndsById[id]==reg) { - continue; // registered already - } - opndsById[id]=reg; - - int num=reg->getValue(); - switch(reg->getOpndKind()) { - case OPND_G_REG: - // ignore r0 r8 - if ((num == 0)|| (num == 8)) { - // r8 - returned value; TODO: more accurate - ignoredOpnds.setBit(id); - } - break; - case OPND_F_REG: - // ignore f0 f1 f8 - if ((num == 0) || (num == 1) || (num == 8)) { - // f8 - returned value; TODO: more accurate - ignoredOpnds.setBit(id); - } - break; - case OPND_P_REG: - // ignore p0 - if (num == 0) { - ignoredOpnds.setBit(id); - } - break; - case OPND_B_REG: - // ignore all br: - ignoredOpnds.setBit(id); - break; - default: ; - } - } -} - -//---------------------------------------------------------------------------// -// check live sets -//---------------------------------------------------------------------------// - -void VertexBB::setDefUse() { - // iterate through instructions postorder and calculate liveSet for begining of the node - InstVector& insts = node->getInsts(); - for (int j=insts.size()-1; j>=0; j--) { - Inst* inst=insts[j]; - uint numDst=inst->getNumDst(); - OpndVector& opnds = inst->getOpnds(); // get inst opnds - - if (((RegOpnd*) opnds[0])->getValue() == 0) { // qp==p0 - for (uint k=1; kisReg()) continue; // ignore non register opnd - uint id=opnd->getId(); - def->setBit(id); - use->setBit(id, false); - } - // TODO: If no one opnd was in Live Set - inst is dead - } else { - // add qp opnd in Use Set - use->setBit(opnds[0]->getId()); - } - // add src opnds in Use Set - for (uint k=numDst+1; kisReg()) continue; // ignore non register opnd - use->setBit(opnd->getId()); - } - fSolver.registerOpnds(opnds); - } -} - -void IpfCfgVerifier::setDefUse() { - for (int k=numNodes-1; k>=0; k--) { - Node* node=nodes[k]; - if (node->getNodeKind()==NODE_BB) { - VertexBB* vertex=getVertexBB((BbNode*)node); - vertex->setDefUse(); - } - } -} - -void Vertex::computeIn() { - // out[B] := U in[S] - EdgeVector& outEdges=getOutEdges(); - uint size=outEdges.size(); - if (size==0) return; - Vertex* succ=fSolver.getTargetVertex(outEdges[0]); - out->copyFrom(*(succ->in)); - for (uint k=1; kunionWith(*(succ->in)); - } - // in[B] == out[B] -} - -void VertexBB::computeIn() { - // out[B] := U in[S] - Vertex::computeIn(); - // in[B] := use[B} U (out[B] - def[B]) - in->copyFrom(*out); - in->subtract(*def); - in->unionWith(*use); -} - -//---------------------------------------------------------------------------// -//bool VertexBB::checkLiveSet() { -bool Vertex::checkLiveSet() { - - RegOpndSet& liveSet = node->getLiveSet(); - BitSet& dceIn=fSolver.tmpSet; - BitSet& tmpSet=fSolver.tmpSet2; - dceIn.clear(); - - for (RegOpndSetIterator i=liveSet.begin(); i!=liveSet.end(); i++) { - Opnd* opnd = (Opnd*)(*i); - IPF_ASSERT(opnd!=NULL); - uint id = opnd->getId(); - dceIn.setBit(id); - } - dceIn.subtract(fSolver.ignoredOpnds); // ignore p0, r0, f0 etc - in->subtract(fSolver.ignoredOpnds); - if (in->isEqual(dceIn)) return true; - - IPF_LOG << "checkLiveSets: DCE and IpfCfgVerifier results differs for node" << node->getId() << endl; - bool res=true; - tmpSet.copyFrom(dceIn); - tmpSet.subtract(*in); - if (!tmpSet.isEmpty()) { - if (LOG_ON) { - fSolver.printOpndSet(LOG_OUT, " DCE has ", tmpSet); - } -// res=false; commented out while too many failures to concide - } - - tmpSet.copyFrom(*in); - tmpSet.subtract(dceIn); - if (!tmpSet.isEmpty()) { - if (LOG_ON) { - fSolver.printOpndSet(LOG_OUT, " IpfCfgVerifier has ", tmpSet); - } - res=false; - } - - return res; -} - -//---------------------------------------------------------------------------// - -bool IpfCfgVerifier::collectLiveSets() { - bool changed = false; - for (int k=numNodes-1; k>=0; k--) { - Vertex* vertex=vertices[k]; - tmpSet.copyFrom(*vertex->in); // save to compare - vertex->computeIn(); -//printf(" %s%d", vertex->in->getBit(9)?"*":" ", vertex->node->getId()); - if (!changed) { - changed = !vertex->in->isEqual(tmpSet); // compare - } - } -//printf("\n"); - return changed; -} - -//---------------------------------------------------------------------------// -bool IpfCfgVerifier::checkLiveSets() { - setDefUse(); -//printf("IpfCfgVerifier::checkLiveSets():\n"); - // solve the flow equation set - while (collectLiveSets()) {}; - - // compare our results with DCE results - bool res = true; - for (uint k=0; kcheckLiveSet() & res; - } - if (res) { - if (LOG_ON) { - IPF_LOG << "ignoredOpnds="; - ignoredOpnds.print(LOG_OUT); - } - } - return res; -} - -//---------------------------------------------------------------------------// -// check defs -//---------------------------------------------------------------------------// - -void VertexBB::setDef(Inst* inst) { - uint numDst=inst->getNumDst(); - OpndVector& opnds = inst->getOpnds(); // get inst opnds - -// if (((RegOpnd*) opnds[0])->getLocation() == 0) { // qp==p0 -// TODO: handle conditional instructions more accurate - for (uint k=1; kisReg()) continue; // ignore non register opnd - uint id=opnd->getId(); - def->setBit(id); - } -} - -void VertexBB::setDef() { - // iterate through instructions in direct order - InstVector& insts = node->getInsts(); - for (uint j=0; jgetOpnds(); // get inst opnds - fSolver.registerOpnds(opnds); - } -} - -//---------------------------------------------------------------------------// -void IpfCfgVerifier::setDefs() { - OpndVector args; // = cfg.getArgs(); - BitSet* enterIn=getVertex(cfg.getEnterNode())->in; - for (uint k=0; ksetBit(args[k]->getId()); - } - - for (uint k=0; kgetNodeKind()==NODE_BB) { - VertexBB* vertex=getVertexBB((BbNode*)node); - vertex->setDef(); - } - } - - // after opnds registered and ignoredOpnds collected - enterIn->unionWith(ignoredOpnds); - for (uint k=0; kout->setAll(); - if (node->getNodeKind()==NODE_BB) { - ((VertexBB*)vertex)->def->unionWith(ignoredOpnds); - } - } -} - -void Vertex::computeOut() { - // in[B] := & out[Preds] - EdgeVector& inEdges=getInEdges(); - uint size=inEdges.size(); - if (size==0) return; - Vertex* pred=fSolver.getSourceVertex(inEdges[0]); - in->copyFrom(*(pred->out)); - for (uint k=1; kintersectWith(*(pred->out)); - } - // out[B] := in[B] -} - -void VertexBB::computeOut() { - Vertex::computeOut(); - // out[B] := in[B] U def[B] - out->copyFrom(*in); - out->unionWith(*def); -} - -//---------------------------------------------------------------------------// - -bool IpfCfgVerifier::collectDefs() { - bool changed = false; - for (uint k=0; kout); // save to compare - vertex->computeOut(); - -// bool vchanged = !vertex->out->isEqual(tmpSet); // compare - if (!changed) { - changed = !vertex->out->isEqual(tmpSet); // compare - } - } - return changed; -} - -bool VertexBB::checkOpndIsDef(Opnd* opnd, uint instId) { - uint id=opnd->getId(); - if (def->getBit(id)) return true; - IPF_LOG << "UNDEF Opnd: " << IrPrinter::toString(opnd) << " in " - << node->getId() << ":" << instId << " " - << IrPrinter::toString((node->getInsts())[instId]) << endl; - return false; -} - -bool VertexBB::checkDefs() { - bool res=true; - // iterate through instructions in direct order - InstVector& insts = ((BbNode*)node)->getInsts(); - def->copyFrom(*in); - for (uint j=0; jgetNumDst(); - OpndVector& opnds = inst->getOpnds(); // get inst opnds - - // check src opnds - RegOpnd* qp = (RegOpnd*)opnds[0]; - if (qp->getValue() != 0) { // qp != p0, check qp opnd - res = checkOpndIsDef(qp, j) & res; - } - for (uint k=numDst+1; kisReg()) continue; // ignore non register opnd - res = checkOpndIsDef(opnd, j) & res; - } - - // handle dst opnds - setDef(inst); - } - return res; -} - -//---------------------------------------------------------------------------// -bool IpfCfgVerifier::checkDefs() { - setDefs(); - - // solve the flow equation set - while (collectDefs()) {}; - - bool res = true; - for (uint k=0; kcheckDefs() & res; - } - return res; -} - -//---------------------------------------------------------------------------// -void ipfCfgVerifier(Cfg& cfg) { - MemoryManager mm(1024, "IpfCfgVerifier"); - IpfCfgVerifier verifier(mm, cfg); - MethodDesc* method = cfg.getMethodDesc(); - const char* methodName = method->getName(); - const char* methodTypeName = (method->getParentType()!=NULL - ? method->getParentType()->getName() - : ""); - const char * methodSignature = method->getSignatureString(); - - if (!verifier.verifyNodes(LOG_OUT)) { - cout << "CFG check failed for " << methodTypeName << "." << methodName << methodSignature << endl; - } - // print - if (LOG_ON) { - verifier.sortNodes(SEARCH_DIRECT_ORDER).printContent(LOG_OUT); - } - - if (!verifier.checkLiveSets()) { - cout << "liveset check failed for [" << cfg.getMaxNodeId() << "] " << methodTypeName << "." << methodName << methodSignature << endl; - } - if (!verifier.checkDefs()) { - cout << "def check failed for [" << cfg.getMaxNodeId() << "] " << methodTypeName << "." << methodName << methodSignature << endl; - } - -} - } // IPF } // Jitrino -// TODO: -// debug this file saved in ~/saved