=================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfDce.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfDce.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$ * */ @@ -37,12 +36,11 @@ class Dce { public: - Dce(Cfg &cfg_) : cfg(cfg_) {} + Dce(Cfg &cfg) : cfg(cfg), currLiveSet(cfg.getMM()) {} void eliminate(); protected: bool isInstDead(Inst*); - void removeInst(InstVector&, InstIterator); Cfg &cfg; RegOpndSet currLiveSet; Index: vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.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$ * */ @@ -181,6 +180,8 @@ RegOpnd *getP0(); RegOpnd *getB0(); RegOpnd *getR12(); + RegOpnd *getR8(); + RegOpnd *getF8(); RegOpnd *getTau(); void setContainCall(bool containCall_) { containCall = containCall_; } @@ -192,7 +193,6 @@ // Reg allocation support //----------------------------------------------------------------------------// - void assignLocation(RegOpnd*); int32 newLocation(OpndKind, DataKind, RegBitSet, bool); int32 newScratchReg(OpndKind, RegBitSet&); int32 newPreservReg(OpndKind, RegBitSet&); @@ -230,6 +230,8 @@ RegOpnd *p0; // true RegOpnd *b0; // return address RegOpnd *r12; // stack pointer + RegOpnd *r8; // return value (general) + RegOpnd *f8; // return value (floating point) RegOpnd *tau; // opnd ignored RegOpnd *heapBase; // opnd containing base for references decompression Index: vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeInterface.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeInterface.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeInterface.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/include/IpfLiveAnalyzer.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfLiveAnalyzer.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfLiveAnalyzer.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ Index: vm/jitrino/src/codegenerator/ipf/include/IpfPrologEpilogGenerator.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfPrologEpilogGenerator.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfPrologEpilogGenerator.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$ * */ @@ -70,7 +69,7 @@ Cfg &cfg; OpndManager *opndManager; - RegOpndVector outRegArgs; // list of out arg registers + RegOpndSet outRegArgs; // list of out arg registers bool containCall; // method contains call Opnd *p0; // p0 (true predicate) Opnd *sp; // gr12 (stack pointer) Index: vm/jitrino/src/codegenerator/ipf/include/IpfVerifier.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfVerifier.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfVerifier.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/include/IpfSpillGen.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfSpillGen.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfSpillGen.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -55,7 +54,7 @@ static string toString(EdgeKind); static string toString(OpndKind); static string toString(DataKind); - + protected: void printEdgeDot(Edge*); void printNodeDot(Node*); Index: vm/jitrino/src/codegenerator/ipf/include/IpfEncoder.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfEncoder.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfEncoder.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$ * */ @@ -570,8 +569,7 @@ //class Cfg; //typedef vector OpndVector; //typedef vector InstVector; -//typedef vector CompVector; -typedef vector CompVector; +typedef StlVector CompVector; class Encoder { public: Index: vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeSupport.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeSupport.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfRuntimeSupport.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$ * */ @@ -43,9 +42,9 @@ // Typedefs //========================================================================================// -typedef vector < TryRegion* > RegionVector; -typedef vector < SafePoint > SafePointVector; -typedef map < RegOpnd*, MptrDef > MptrDefMap; +typedef StlVector < TryRegion* > RegionVector; +typedef StlVector < SafePoint > SafePointVector; +typedef StlMap < RegOpnd*, MptrDef > MptrDefMap; typedef MptrDefMap::iterator MptrDefMapIterator; @@ -83,8 +82,8 @@ class SafePoint { public: - SafePoint() { node=NULL; inst=NULL; } - SafePoint(BbNode *node, Inst *inst) : node(node), inst(inst) {} + SafePoint(MemoryManager &mm) : node(NULL), inst(NULL), alivePtrs(mm) {} + SafePoint(MemoryManager &mm, BbNode *node, Inst *inst) : node(node), inst(inst), alivePtrs(mm) {} BbNode *node; Inst *inst; Index: vm/jitrino/src/codegenerator/ipf/include/IpfType.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfType.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfType.h (working copy) @@ -17,18 +17,13 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ #ifndef IPFTYPE_H_ #define IPFTYPE_H_ -#include -#include -#include #include -#include #include #include #include @@ -36,6 +31,7 @@ #include #include "Type.h" #include "Log.h" +#include "Stl.h" #include "VMInterface.h" using namespace std; @@ -194,21 +190,23 @@ // Typedefs //========================================================================================// -typedef vector< Opnd* > OpndVector; -typedef vector< RegOpnd* > RegOpndVector; -typedef vector< Inst* > InstVector; -typedef vector< Node* > NodeVector; -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; -typedef map< Inst*, RegOpndSet > Inst2RegOpndSetMap; -typedef map< uint64, RegOpndSet > Uint642RegOpndSetMap; -typedef bitset< NUM_G_REG > RegBitSet; +typedef StlVector< Opnd* > OpndVector; +typedef StlVector< RegOpnd* > RegOpndVector; +typedef StlVector< Inst* > InstVector; +typedef StlVector< Node* > NodeVector; +typedef StlVector< Edge* > EdgeVector; +typedef StlVector< uint32 > Uint32Vector; +typedef StlList< Inst* > InstList; +typedef StlList< Node* > NodeList; +typedef StlList< Edge* > EdgeList; +typedef StlSet< Opnd* > OpndSet; +typedef StlSet< RegOpnd* > RegOpndSet; +typedef StlSet< Node* > NodeSet; +typedef StlMap< RegOpnd*, RegOpnd* > RegOpnd2RegOpndMap; +typedef StlMap< Inst*, RegOpndSet > Inst2RegOpndSetMap; +typedef StlMap< uint64, RegOpndSet > Uint642RegOpndSetMap; +typedef bitset< NUM_G_REG > RegBitSet; +typedef StlMultiMap > Int2OpndMap; typedef NodeVector::iterator NodeIterator; typedef InstVector::iterator InstIterator; @@ -219,11 +217,12 @@ typedef InstList::iterator InstListIterator; typedef NodeList::iterator NodeListIterator; typedef EdgeList::iterator EdgeListIterator; +typedef RegOpnd2RegOpndMap::iterator RegOpnd2RegOpndMapIterator; typedef Inst2RegOpndSetMap::iterator Inst2RegOpndSetMapIterator; typedef Uint642RegOpndSetMap::iterator Uint642RegOpndSetMapIterator; typedef NodeList Chain; -typedef list< Chain* > ChainList; +typedef StlList< Chain* > ChainList; typedef multimap< uint32, Chain*, greater < uint32 > > ChainMap; typedef Chain::iterator ChainIterator; typedef ChainList::iterator ChainListIterator; Index: vm/jitrino/src/codegenerator/ipf/include/IpfRegisterAllocator.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfRegisterAllocator.h (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/include/IpfRegisterAllocator.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,23 +34,26 @@ class RegisterAllocator { public: - RegisterAllocator(Cfg&); - void allocate(); + RegisterAllocator(Cfg&); + void allocate(); protected: - void buildInterferenceMatrix(); - void makeInterferenceMatrixSymmetric(); - void removePreassignedOpnds(); - void assignLocations(); + void buildInterferenceMatrix(); + void removeSelfDep(); + void assignLocations(); - void updateAllocSet(Opnd*, uint32); - void checkCallSite(Inst*); + void assignLocation(RegOpnd*); + void updateAllocSet(Opnd*, uint32); + void checkCallSite(Inst*); + + void checkCoalescing(uint32, Inst*); + void removeSameRegMoves(); - MemoryManager &mm; - Cfg &cfg; - OpndManager *opndManager; - RegOpndSet allocSet; // set of all opnds that need allocation - RegOpndSet liveSet; // set of opnds alive in current node (buildInterferenceMatrix) + MemoryManager &mm; + Cfg &cfg; + OpndManager *opndManager; + RegOpndSet allocSet; // set of all opnds that need allocation + RegOpndSet liveSet; // set of opnds alive in current node (buildInterferenceMatrix) }; } // IPF Index: vm/jitrino/src/codegenerator/ipf/IpfRuntimeInterface.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfRuntimeInterface.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfRuntimeInterface.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$ * */ @@ -39,8 +38,7 @@ JitFrameContext *jitFrameContext, bool isFirst) { -// cout << "IPF::RuntimeInterface::unwindStack "; -// cout << methodDesc->getName() << " " << methodDesc->getSignatureString() << endl; + // cout << "IPF::RuntimeInterface::unwindStack " << methodDesc->getName() << endl; Byte *infoBlock = methodDesc->getInfoBlock(); // get method infoBlock StackInfo stackInfo = *((StackInfo*) infoBlock); // read StackInfo structure @@ -131,6 +129,8 @@ const JitFrameContext *context_, bool isFirst) { + // cout << "IPF::RuntimeInterface::getGCRootSet" << endl; + gcInterface = gcInterface_; context = context_; Byte *infoBlock = methodDesc->getInfoBlock(); @@ -147,7 +147,7 @@ uint32 RuntimeInterface::getInlineDepth(InlineInfoPtr ptr, uint32 offset) { - cerr << "IPF::RuntimeInterface::getInlineDepth" << endl; + cout << "IPF::RuntimeInterface::getInlineDepth" << endl; return 0; } @@ -157,7 +157,7 @@ uint32 offset, uint32 inline_depth) { - cerr << "IPF::RuntimeInterface::getInlinedMethod" << endl; + cout << "IPF::RuntimeInterface::getInlinedMethod" << endl; return NULL; } @@ -165,13 +165,15 @@ bool RuntimeInterface::canEnumerate(MethodDesc *methodDesc, NativeCodePtr eip) { - cerr << "IPF::RuntimeInterface::canEnumerate" << endl; + cout << "IPF::RuntimeInterface::canEnumerate" << endl; return true; } //----------------------------------------------------------------------------------------// -void RuntimeInterface::fixHandlerContext(MethodDesc *methodDesc, JitFrameContext *context, bool isFirst) {} +void RuntimeInterface::fixHandlerContext(MethodDesc *methodDesc, JitFrameContext *context, bool isFirst) { +// cout << "IPF::RuntimeInterface::fixHandlerContext" << endl; +} //----------------------------------------------------------------------------------------// @@ -179,6 +181,7 @@ const ::JitFrameContext *jitFrameContext, bool isFirst) { +// cout << "IPF::RuntimeInterface::getAddressOfThis" << endl; assert(!methodDesc->isStatic()); return jitFrameContext->p_gr[G_INARG_BASE]; } @@ -188,7 +191,7 @@ void* RuntimeInterface::getAddressOfSecurityObject(MethodDesc *methodDesc, const ::JitFrameContext *jitFrameContext) { - cerr << "IPF::RuntimeInterface::getAddressOfSecurityObject" << endl; + cout << "IPF::RuntimeInterface::getAddressOfSecurityObject" << endl; assert(0); return NULL; } @@ -199,6 +202,8 @@ MethodDesc *methodDesc, void *data) { +// cout << "IPF::RuntimeInterface::recompiledMethodEvent " << methodDesc->getName() << endl; + char *callAddr = (char *)(~(((uint64)0x4cafe) << 32) & (uint64)data); char **indirectAddr = (char **)methodDesc->getIndirectAddress(); char *methodAddr = *indirectAddr; @@ -210,16 +215,17 @@ bool RuntimeInterface::getBcLocationForNative(MethodDesc *method, uint64 native_pc, uint16 *bc_pc) { - cerr << "IPF::RuntimeInterface::getBcLocationForNative" << endl; - assert(0); - return false; +// cout << "IPF::RuntimeInterface::getBcLocationForNative" << endl; +// assert(0); +// return false; + return true; } //----------------------------------------------------------------------------------------// bool RuntimeInterface::getNativeLocationForBc(MethodDesc *method, uint16 bc_pc, uint64 *native_pc) { - cerr << "IPF::RuntimeInterface::getNativeLocationForBc" << endl; + cout << "IPF::RuntimeInterface::getNativeLocationForBc" << endl; assert(0); return false; } Index: vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfLiveAnalyzer.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$ * */ @@ -38,7 +37,7 @@ void LiveAnalyzer::makeLiveSets(bool verify_) { - IPF_LOG << endl; +// IPF_LOG << endl; verify = verify_; NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); // get postordered node list @@ -64,25 +63,25 @@ bool LiveAnalyzer::analyzeNode(Node *node) { // build live set for node - RegOpndSet currLiveSet; + RegOpndSet currLiveSet(cfg.getMM()); RegOpndSet &oldLiveSet = node->getLiveSet(); node->mergeOutLiveSets(currLiveSet); // put in the live set merged live sets of successors - if (LOG_ON) { - IPF_LOG << " node" << node->getId() << " successors:"; - EdgeVector &edges = node->getOutEdges(); - for (uint16 i=0; igetTarget(); - Node *loopHeader = succ->getLoopHeader(); - IPF_LOG << " " << succ->getId(); - if (loopHeader != NULL) IPF_LOG << "(" << loopHeader->getId() << ")"; - } - IPF_LOG << " exit live set: " << IrPrinter::toString(currLiveSet) << endl; - } +// if (LOG_ON) { +// IPF_LOG << " node" << node->getId() << " successors:"; +// EdgeVector &edges = node->getOutEdges(); +// for (uint16 i=0; igetTarget(); +// Node *loopHeader = succ->getLoopHeader(); +// IPF_LOG << " " << succ->getId(); +// if (loopHeader != NULL) IPF_LOG << "(" << loopHeader->getId() << ")"; +// } +// IPF_LOG << " exit live set: " << IrPrinter::toString(currLiveSet) << endl; +// } // If node is not BB - currLiveSet is not going to change if(node->getNodeKind() != NODE_BB) { - IPF_LOG << " node is not BB - live set is not changed" << endl; +// IPF_LOG << " node is not BB - live set is not changed" << endl; if (oldLiveSet == currLiveSet) return true; // if live set has not changed - nothing to do node->setLiveSet(currLiveSet); // Set currLiveSet for the current node @@ -94,11 +93,7 @@ InstIterator firstInst = insts.begin()-1; for(; currInst>firstInst; currInst--) { - updateLiveSet(currLiveSet, *currInst); - - IPF_LOG << " " << left << setw(46) << IrPrinter::toString(*currInst); - IPF_LOG << " live set : " << IrPrinter::toString(currLiveSet) << endl; } if (oldLiveSet == currLiveSet) return true; // if live set has not changed - nothing to do Index: vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.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$ * */ @@ -676,7 +675,7 @@ RegOpnd *arg = opndManager->newRegOpnd(opndKind, dataKind, location); IPF_LOG << " defArg " << IrPrinter::toString(arg) << " " << type->getName() << endl; -// addNewInst(INST_DEF, p0, arg); // artificial def for in arg opnd +// addNewInst(INST_DEF, p0, arg); // artificial def for in arg opnd if (isFp) { RegOpnd *newarg = opndManager->newRegOpnd(opndKind, dataKind); addNewInst(INST_MOV, p0, newarg, arg); // if fp arg crosses call site @@ -810,7 +809,7 @@ NodeRef *target = opndManager->newNodeRef(); cmp(instCode, crel, truePred, p0, src1, src2); - addNewInst(INST_BR, CMPLT_BTYPE_COND, truePred, target); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); } //----------------------------------------------------------------------------// @@ -834,7 +833,7 @@ } cmp(instCode, CMPLT_CMP_CREL_EQ, truePred, p0, src, zero); - addNewInst(INST_BR, CMPLT_BTYPE_COND, truePred, target); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); } //----------------------------------------------------------------------------// @@ -858,7 +857,7 @@ } cmp(instCode, CMPLT_CMP_CREL_NE, truePred, p0, src, zero); - addNewInst(INST_BR, CMPLT_BTYPE_COND, truePred, target); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); } //----------------------------------------------------------------------------// @@ -882,7 +881,7 @@ IPF_LOG << " tableSwitch" << endl; - Constant *switchTable = new(mm) SwitchConstant(); + Constant *switchTable = new(mm) SwitchConstant(mm); Opnd *r0 = opndManager->getR0(); Opnd *p6 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); // default target is taken @@ -911,10 +910,10 @@ // compare with default addNewInst(INST_CMP4, CMPLT_CMP_CREL_GT, CMPLT_CMP_CTYPE_UNC, p0, p6, p7, tgt, maxTgt); - Inst *tmpinst = new(mm) Inst(INST_CMP4, CMPLT_CMP_CREL_LT, CMPLT_CMP_CTYPE_OR_ANDCM, p7, p6, p7, tgt, r0); + Inst *tmpinst = new(mm) Inst(mm, INST_CMP4, CMPLT_CMP_CREL_LT, CMPLT_CMP_CTYPE_OR_ANDCM, p7, p6, p7, tgt, r0); tmpinst->addOpnd(p6); tmpinst->addOpnd(p7); - node.addInst(tmpinst); + addInst(tmpinst); addNewInst(INST_MOV, p6, tgt, defTgt); // compare if through target @@ -1150,7 +1149,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_NullPtrException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau) } @@ -1171,7 +1170,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1192,7 +1191,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1213,7 +1212,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1253,7 +1252,7 @@ hId = CompilationInterface::Helper_ElemTypeException; address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress2 = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress2, truePred); + directCall(0, NULL, NULL, helperAddress2, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1275,7 +1274,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_DivideByZeroException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); return opndManager->getTau(); // return fake value (we do not use tau) } @@ -1471,24 +1470,24 @@ CG_OpndHandle *IpfInstCodeSelector::getVTableAddr(Type *dstType, ObjectType *base) { - IPF_LOG << " getVTableAddr; dstType==" << Type::tag2str(dstType->tag) << endl; - uint64 value = (uint64) base->getVTable(); - if (dstType->tag==Type::VTablePtr && opndManager->areVtablePtrsCompressed()) { value += (uint64) compilationInterface.getVTableBase(); } Opnd *addr = opndManager->newImm(value); + IPF_LOG << " getVTableAddr" << endl << " addr " << IrPrinter::toString(addr) << endl; + return addr; } //----------------------------------------------------------------------------// // Load interface table address -CG_OpndHandle *IpfInstCodeSelector::tau_ldIntfTableAddr(Type *dstType, - CG_OpndHandle *base, - NamedType *vtableType) { +CG_OpndHandle *IpfInstCodeSelector::tau_ldIntfTableAddr(Type *dstType, + CG_OpndHandle *base, + NamedType *vtableType, + CG_OpndHandle *) { IPF_LOG << " tau_ldIntfTableAddr; dstType==" << Type::tag2str(dstType->tag) << "; vtableType=" << Type::tag2str(vtableType->tag) << endl; @@ -1813,44 +1812,46 @@ //----------------------------------------------------------------------------// // Create direct call to the method -void IpfInstCodeSelector::directCall(uint32 numArgs, - Opnd **args, - RegOpnd *retOpnd, - Opnd *methodAddress, - RegOpnd *pred) { +void IpfInstCodeSelector::directCall(uint32 numArgs, + Opnd **args, + RegOpnd *retOpnd, + Opnd *methodAddress, + RegOpnd *pred, + Completer whetherHint) { RegOpnd *b0 = opndManager->getB0(); RegOpnd *convOpnd = makeConvOpnd(retOpnd); - Inst *callInst = new(mm) Inst(INST_BRL13, CMPLT_BTYPE_CALL, CMPLT_WH_SPTK, CMPLT_PH_MANY + Inst *callInst = new(mm) Inst(mm, INST_BRL13, CMPLT_BTYPE_CALL, whetherHint, CMPLT_PH_MANY , pred, convOpnd, b0, methodAddress); opndManager->setContainCall(true); // set flag OpndManager::containCall makeCallArgs(numArgs, args, callInst, pred); // add instructions moving args in appropriate locations - node.addInst(callInst); // add "call" inst + addInst(callInst); // add "call" inst makeRetVal(retOpnd, convOpnd, pred); // add instruction moving ret value from r8/f8 } //----------------------------------------------------------------------------// // Create indirect call to the method -void IpfInstCodeSelector::indirectCall(uint32 numArgs, - Opnd **args, - RegOpnd *retOpnd, - RegOpnd *methodPtr, - RegOpnd *pred) { +void IpfInstCodeSelector::indirectCall(uint32 numArgs, + Opnd **args, + RegOpnd *retOpnd, + RegOpnd *methodPtr, + RegOpnd *pred, + Completer whetherHint) { RegOpnd *b0 = opndManager->getB0(); RegOpnd *convOpnd = makeConvOpnd(retOpnd); RegOpnd *callTgt = opndManager->newRegOpnd(OPND_B_REG, DATA_U64); - Inst *ldAddress = new(mm) Inst(INST_MOV, pred, callTgt, methodPtr); - Inst *callInst = new(mm) Inst(INST_BR13, CMPLT_BTYPE_CALL, pred, convOpnd, b0, callTgt); + Inst *ldAddress = new(mm) Inst(mm, INST_MOV, pred, callTgt, methodPtr); + Inst *callInst = new(mm) Inst(mm, INST_BR13, CMPLT_BTYPE_CALL, CMPLT_WH_SPTK, CMPLT_PH_MANY, pred, convOpnd, b0, callTgt); opndManager->setContainCall(true); // set flag OpndManager::containCall (method contains call) makeCallArgs(numArgs, args, callInst, pred); // add instructions moving args in appropriate locations - node.addInst(ldAddress); // add inst loading method address - node.addInst(callInst); // add "call" inst + addInst(ldAddress); // add inst loading method address + addInst(callInst); // add "call" inst makeRetVal(retOpnd, convOpnd, pred); // add instruction moving ret value from r8/f8 } @@ -1899,14 +1900,8 @@ if(retOpnd == NULL) return opndManager->getR0(); // method has return type "void" - OpndKind opndKind = retOpnd->getOpndKind(); - DataKind dataKind = retOpnd->getDataKind(); - int32 location = LOCATION_INVALID; - - if (retOpnd->isFloating()) location = RET_F_REG; - else location = RET_G_REG; - - return opndManager->newRegOpnd(opndKind, dataKind, location); + if (retOpnd->isFloating()) return opndManager->getF8(); + else return opndManager->getR8(); } //----------------------------------------------------------------------------// @@ -2604,6 +2599,14 @@ // create new inst and add it in current node //----------------------------------------------------------------------------// +void IpfInstCodeSelector::addInst(Inst *inst) { + + IPF_LOG << " " << IrPrinter::toString(inst) << endl; + node.addInst(inst); +} + +//----------------------------------------------------------------------------// + Inst& IpfInstCodeSelector::addNewInst(InstCode instCode, CG_OpndHandle *op1, CG_OpndHandle *op2, @@ -2612,9 +2615,9 @@ CG_OpndHandle *op5, CG_OpndHandle *op6) { - Inst* inst = new(mm) Inst(instCode, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, + Inst* inst = new(mm) Inst(mm, instCode, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, (Opnd *)op4, (Opnd *)op5, (Opnd *)op6); - node.addInst(inst); + addInst(inst); return *inst; } @@ -2629,9 +2632,9 @@ CG_OpndHandle *op5, CG_OpndHandle *op6) { - Inst* inst = new(mm) Inst(instCode, comp1, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, + Inst* inst = new(mm) Inst(mm, instCode, comp1, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, (Opnd *)op4, (Opnd *)op5, (Opnd *)op6); - node.addInst(inst); + addInst(inst); return *inst; } @@ -2647,13 +2650,32 @@ CG_OpndHandle *op5, CG_OpndHandle *op6) { - Inst* inst = new(mm) Inst(instCode, comp1, comp2, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, + Inst* inst = new(mm) Inst(mm, instCode, comp1, comp2, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, (Opnd *)op4, (Opnd *)op5, (Opnd *)op6); - node.addInst(inst); + addInst(inst); return *inst; } //----------------------------------------------------------------------------// + +Inst& IpfInstCodeSelector::addNewInst(InstCode instCode, + Completer comp1, + Completer comp2, + Completer comp3, + CG_OpndHandle *op1, + CG_OpndHandle *op2, + CG_OpndHandle *op3, + CG_OpndHandle *op4, + CG_OpndHandle *op5, + CG_OpndHandle *op6) { + + Inst* inst = new(mm) Inst(mm, instCode, comp1, comp2, comp3, (Opnd *)op1, (Opnd *)op2, (Opnd *)op3, + (Opnd *)op4, (Opnd *)op5, (Opnd *)op6); + addInst(inst); + return *inst; +} + +//----------------------------------------------------------------------------// // convertors from HLO to CG types //----------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/IpfPrologEpilogGenerator.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfPrologEpilogGenerator.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfPrologEpilogGenerator.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$ * */ @@ -31,9 +30,30 @@ // PrologEpilogGenerator //========================================================================================// -PrologEpilogGenerator::PrologEpilogGenerator(Cfg &cfg_) : - mm(cfg_.getMM()), - cfg(cfg_) { +PrologEpilogGenerator::PrologEpilogGenerator(Cfg &cfg) : + mm(cfg.getMM()), + cfg(cfg), + outRegArgs(mm), + prologInsts(mm), + epilogInsts(mm), + allocInsts(mm), + saveSpInsts(mm), + savePfsInsts(mm), + saveUnatInsts(mm), + saveGrsInsts(mm), + saveFrsInsts(mm), + saveBrsInsts(mm), + savePrsInsts(mm), + saveRpInsts(mm), + restRpInsts(mm), + restPrsInsts(mm), + restBrsInsts(mm), + restFrsInsts(mm), + restGrsInsts(mm), + restUnatInsts(mm), + restPfsInsts(mm), + restSpInsts(mm), + epilogNodes(mm) { opndManager = cfg.getOpndManager(); p0 = opndManager->getP0(); @@ -54,10 +74,9 @@ void PrologEpilogGenerator::genPrologEpilog() { - IPF_LOG << endl << " Build Data Sets" << endl; buildSets(); - IPF_LOG << " Generate Code" << endl; + IPF_LOG << endl << " Generate Code" << endl; genCode(); IPF_LOG << " Reassign OutRegArgs" << endl; @@ -77,14 +96,15 @@ for(uint16 i=0; igetNodeKind() != NODE_BB) continue; // ignore non BB node + InstVector &insts = ((BbNode *)nodes[i])->getInsts(); // get insts + if(insts.size() == 0) continue; // if there are no insts in node - ignore + // check if node is epilog and insert it in epilogNodes list - if(insts.size() > 0) { // if there are insts in node - CompVector &comps = insts.back()->getComps(); // get last one completers - if(comps.size()>0 && comps[0]==CMPLT_BTYPE_RET) { // if the inst is br.ret - node is epilog - epilogNodes.push_back(nodes[i]); // put it in epilogNodes list - } + CompVector &comps = insts.back()->getComps(); // get last inst completers + if(comps.size()>0 && comps[0]==CMPLT_BTYPE_RET) { // if the inst is br.ret - node is epilog + epilogNodes.push_back(nodes[i]); // put it in epilogNodes list } // build mask of used registers and vector of outArgs @@ -96,7 +116,7 @@ setRegUsage(opnd, true); // mark reg as used if (opndManager->isOutReg(opnd)) { // if opnd is out arg - outRegArgs.push_back(opnd); // place it in ouRegArgs vector + outRegArgs.insert(opnd); // place it in ouRegArgs vector } } } @@ -112,17 +132,18 @@ // First out arg will have this location int32 outArgBase = G_INARG_BASE + opndManager->getLocRegSize(); - for(uint16 i=0; igetValue(); // calculate real out arg number - outRegArgs[i]->setLocation(outArgBase + outArgNum); // calculate and assign new location - setRegUsage(outRegArgs[i], true); // mark new reg as used - IPF_LOG << IrPrinter::toString(outRegArgs[i]) << endl; + RegOpnd *arg = *it; + IPF_LOG << " " << IrPrinter::toString(arg) << " reassigned on "; + int32 outArgNum = G_OUTARG_BASE - arg->getValue(); // calculate real out arg number + arg->setLocation(outArgBase + outArgNum); // calculate and assign new location + setRegUsage(arg, true); // mark new reg as used + IPF_LOG << IrPrinter::toString(arg) << endl; } } @@ -191,8 +212,7 @@ epilogInsts.splice(epilogInsts.end(), restSpInsts); // Print Prolog and Epilog insts - IPF_LOG << endl; - IPF_LOG << " Prolog:" << endl << IrPrinter::toString(prologInsts) << endl; + IPF_LOG << " Prolog:" << endl << IrPrinter::toString(prologInsts); IPF_LOG << " Epilog:" << endl << IrPrinter::toString(epilogInsts) << endl; // Insert prolog instructions in begining of enter node @@ -223,16 +243,16 @@ Opnd *offset = opndManager->newImm(rpBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); - saveRpInsts.push_back(new(mm) Inst(INST_MOV, p0, scratch, b0)); - saveRpInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - saveRpInsts.push_back(new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); + saveRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, b0)); + saveRpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + saveRpInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); - restRpInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restRpInsts.push_back(new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); - restRpInsts.push_back(new(mm) Inst(INST_MOV, p0, b0, scratch)); + restRpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restRpInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); + restRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, b0, scratch)); } else { - saveRpInsts.push_back(new(mm) Inst(INST_MOV, p0, rpBak, b0)); - restRpInsts.push_back(new(mm) Inst(INST_MOV, p0, b0, rpBak)); + saveRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, rpBak, b0)); + restRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, b0, rpBak)); } } @@ -251,16 +271,16 @@ Opnd *offset = opndManager->newImm(prBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); - savePrsInsts.push_back(new(mm) Inst(INST_MOV, p0, scratch, p0)); - savePrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - savePrsInsts.push_back(new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); + savePrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, p0)); + savePrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + savePrsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); - restPrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restPrsInsts.push_back(new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); - restPrsInsts.push_back(new(mm) Inst(INST_MOV, p0, p0, scratch)); + restPrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restPrsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); + restPrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, p0, scratch)); } else { - savePrsInsts.push_back(new(mm) Inst(INST_MOV, p0, prBak, p0)); - restPrsInsts.push_back(new(mm) Inst(INST_MOV, p0, p0, prBak)); + savePrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, prBak, p0)); + restPrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, p0, prBak)); } } @@ -282,7 +302,7 @@ Opnd *oSize = opndManager->newImm(outRegSize); // number of output gr Opnd *rSize = opndManager->newImm(0); // number of rotate gr - allocInsts.push_back(new(mm) Inst(INST_ALLOC, p0, pfsBak, iSize, lSize, oSize, rSize)); + allocInsts.push_back(new(mm) Inst(mm, INST_ALLOC, p0, pfsBak, iSize, lSize, oSize, rSize)); } //----------------------------------------------------------------------------------------// @@ -305,16 +325,16 @@ Opnd *offset = opndManager->newImm(pfsBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); - savePfsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - savePfsInsts.push_back(new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); + savePfsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + savePfsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); - restPfsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restPfsInsts.push_back(new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); - restPfsInsts.push_back(new(mm) Inst(INST_MOV_I, p0, pfs, scratch)); + restPfsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restPfsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); + restPfsInsts.push_back(new(mm) Inst(mm, INST_MOV_I, p0, pfs, scratch)); return scratch; } else { - restPfsInsts.push_back(new(mm) Inst(INST_MOV_I, p0, pfs, pfsBak)); + restPfsInsts.push_back(new(mm) Inst(mm, INST_MOV_I, p0, pfs, pfsBak)); return pfsBak; } } @@ -335,13 +355,13 @@ opndManager->unatBak = storage->getLocation(); - saveUnatInsts.push_back(new(mm) Inst(INST_MOV_M, p0, scratch, unat)); - saveUnatInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - saveUnatInsts.push_back(new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); + saveUnatInsts.push_back(new(mm) Inst(mm, INST_MOV_M, p0, scratch, unat)); + saveUnatInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + saveUnatInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); - restUnatInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restUnatInsts.push_back(new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); - restUnatInsts.push_back(new(mm) Inst(INST_MOV_M, p0, unat, scratch)); + restUnatInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restUnatInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); + restUnatInsts.push_back(new(mm) Inst(mm, INST_MOV_M, p0, unat, scratch)); } //----------------------------------------------------------------------------------------// @@ -366,10 +386,10 @@ Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *preserv = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, i); - saveGrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - saveGrsInsts.push_back(new(mm) Inst(INST_ST8_SPILL, p0, stackAddr, preserv)); - restGrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restGrsInsts.push_back(new(mm) Inst(INST_LD8_FILL, p0, preserv, stackAddr)); + saveGrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + saveGrsInsts.push_back(new(mm) Inst(mm, INST_ST8_SPILL, p0, stackAddr, preserv)); + restGrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restGrsInsts.push_back(new(mm) Inst(mm, INST_LD8_FILL, p0, preserv, stackAddr)); IPF_LOG << " " << IrPrinter::toString(preserv); } @@ -395,10 +415,10 @@ Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *preserv = opndManager->newRegOpnd(OPND_F_REG, DATA_F, i); - saveFrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - saveFrsInsts.push_back(new(mm) Inst(INST_STF_SPILL, p0, stackAddr, preserv)); - restFrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restFrsInsts.push_back(new(mm) Inst(INST_LDF_FILL, p0, preserv, stackAddr)); + saveFrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + saveFrsInsts.push_back(new(mm) Inst(mm, INST_STF_SPILL, p0, stackAddr, preserv)); + restFrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restFrsInsts.push_back(new(mm) Inst(mm, INST_LDF_FILL, p0, preserv, stackAddr)); IPF_LOG << " " << IrPrinter::toString(preserv); } @@ -423,13 +443,13 @@ Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); Opnd *preserv = opndManager->newRegOpnd(OPND_B_REG, DATA_B, i); - saveBrsInsts.push_back(new(mm) Inst(INST_MOV, p0, scratch, preserv)); - saveBrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - saveBrsInsts.push_back(new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); + saveBrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, preserv)); + saveBrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + saveBrsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); - restBrsInsts.push_back(new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp)); - restBrsInsts.push_back(new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); - restBrsInsts.push_back(new(mm) Inst(INST_MOV, p0, preserv, scratch)); + restBrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); + restBrsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); + restBrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, preserv, scratch)); IPF_LOG << " " << IrPrinter::toString(preserv); } IPF_LOG << endl; @@ -447,8 +467,8 @@ Opnd *memStackSizeOpndNeg = opndManager->newImm(-memStackSize); Opnd *memStackSizeOpndPos = opndManager->newImm(memStackSize); - saveSpInsts.push_back(new(mm) Inst(INST_ADDS, p0, sp, memStackSizeOpndNeg, sp)); - restSpInsts.push_back(new(mm) Inst(INST_ADDS, p0, sp, memStackSizeOpndPos, sp)); + saveSpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, sp, memStackSizeOpndNeg, sp)); + restSpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, sp, memStackSizeOpndPos, sp)); } //----------------------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfVerifier.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/IpfSpillGen.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfSpillGen.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfSpillGen.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,9 +31,11 @@ // SpillGen //========================================================================================// -SpillGen::SpillGen(Cfg &cfg_) : - mm(cfg_.getMM()), - cfg(cfg_) { +SpillGen::SpillGen(Cfg &cfg) : + mm(cfg.getMM()), + cfg(cfg), + fillCode(mm), + spillCode(mm) { opndManager = cfg.getOpndManager(); p0 = opndManager->getP0(); @@ -124,7 +125,7 @@ // Create instruction calculating stack address to store to Opnd *offset = opndManager->newImm(stackOpnd->getValue()); - Inst *adds = new(mm) Inst(INST_ADDS, p0, stackAddr, offset, sp); + Inst *adds = new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp); spillFlag ? spillCode.push_back(adds) : fillCode.push_back(adds); // Create instruction storing value from scratchOpnd on stack @@ -190,7 +191,7 @@ default : IPF_ERR << "invalid size " << IrPrinter::toString(scratchOpnd) << endl; } - Inst *st = new(mm) Inst(INST_ST, completer, p0, stackAddr, scratchOpnd); + Inst *st = new(mm) Inst(mm, INST_ST, completer, p0, stackAddr, scratchOpnd); spillCode.push_back(st); } @@ -211,7 +212,7 @@ default: IPF_ERR << "invalid DataKind " << IrPrinter::toString(scratchOpnd) << endl; } - Inst *st = new(mm) Inst(INST_STF, completer, p0, stackAddr, scratchOpnd); + Inst *st = new(mm) Inst(mm, INST_STF, completer, p0, stackAddr, scratchOpnd); spillCode.push_back(st); } @@ -227,8 +228,8 @@ int32 bufReg = getAvailableSpillReg(OPND_G_REG); Opnd *bufOpnd = opndManager->newRegOpnd(OPND_G_REG, DATA_B, bufReg); - Inst *mov = new(mm) Inst(INST_MOV, p0, bufOpnd, scratchOpnd); - Inst *st = new(mm) Inst(INST_ST, CMPLT_SZ_8, p0, stackAddr, bufOpnd); + Inst *mov = new(mm) Inst(mm, INST_MOV, p0, bufOpnd, scratchOpnd); + Inst *st = new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, bufOpnd); spillCode.push_back(mov); spillCode.push_back(st); @@ -248,9 +249,9 @@ int32 bufReg = getAvailableSpillReg(OPND_G_REG); Opnd *bufOpnd = opndManager->newRegOpnd(OPND_G_REG, DATA_P, bufReg); Opnd *imm1 = opndManager->newImm(1); - Inst *mov1 = new(mm) Inst(INST_MOV, p0, bufOpnd, opndManager->getR0()); - Inst *mov2 = new(mm) Inst(INST_MOV, scratchOpnd, bufOpnd, imm1); - Inst *st = new(mm) Inst(INST_ST, CMPLT_SZ_1, p0, stackAddr, bufOpnd); + Inst *mov1 = new(mm) Inst(mm, INST_MOV, p0, bufOpnd, opndManager->getR0()); + Inst *mov2 = new(mm) Inst(mm, INST_MOV, scratchOpnd, bufOpnd, imm1); + Inst *st = new(mm) Inst(mm, INST_ST, CMPLT_SZ_1, p0, stackAddr, bufOpnd); spillCode.push_back(mov1); spillCode.push_back(mov2); @@ -275,12 +276,12 @@ default : IPF_ERR << "invalid size " << IrPrinter::toString(scratchOpnd) << endl; } - Inst *ld = new(mm) Inst(INST_LD, completer, p0, scratchOpnd, stackAddr); + Inst *ld = new(mm) Inst(mm, INST_LD, completer, p0, scratchOpnd, stackAddr); fillCode.push_back(ld); // Create sxt instruction for int32 data type if(scratchOpnd->getDataKind() == DATA_I32) { - Inst *sxt = new(mm) Inst(INST_SXT, CMPLT_XSZ_4, p0, scratchOpnd, scratchOpnd); + Inst *sxt = new(mm) Inst(mm, INST_SXT, CMPLT_XSZ_4, p0, scratchOpnd, scratchOpnd); fillCode.push_back(sxt); } } @@ -302,7 +303,7 @@ default: IPF_ERR << "invalid DataKind " << IrPrinter::toString(scratchOpnd) << endl; } - Inst *ld = new(mm) Inst(INST_LDF, completer, p0, scratchOpnd, stackAddr); + Inst *ld = new(mm) Inst(mm, INST_LDF, completer, p0, scratchOpnd, stackAddr); fillCode.push_back(ld); } @@ -318,8 +319,8 @@ int32 bufReg = getAvailableSpillReg(OPND_G_REG); Opnd *bufOpnd = opndManager->newRegOpnd(OPND_G_REG, DATA_I64, bufReg); - Inst *ld = new(mm) Inst(INST_LD, CMPLT_SZ_8, p0, bufOpnd, stackAddr); - Inst *mov = new(mm) Inst(INST_MOV, p0, scratchOpnd, bufOpnd); + Inst *ld = new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, bufOpnd, stackAddr); + Inst *mov = new(mm) Inst(mm, INST_MOV, p0, scratchOpnd, bufOpnd); fillCode.push_back(ld); fillCode.push_back(mov); @@ -337,8 +338,8 @@ int32 bufReg = getAvailableSpillReg(OPND_G_REG); Opnd *bufOpnd = opndManager->newRegOpnd(OPND_G_REG, DATA_P, bufReg); - Inst *ld = new(mm) Inst(INST_LD, CMPLT_SZ_1, p0, bufOpnd, stackAddr); - Inst *cmp = new(mm) Inst(INST_CMP, CMPLT_CMP_CREL_NE, p0, scratchOpnd, p0, bufOpnd); + Inst *ld = new(mm) Inst(mm, INST_LD, CMPLT_SZ_1, p0, bufOpnd, stackAddr); + Inst *cmp = new(mm) Inst(mm, INST_CMP, CMPLT_CMP_CREL_NE, p0, scratchOpnd, p0, bufOpnd); cmp->addOpnd(opndManager->getR0()); fillCode.push_back(ld); Index: vm/jitrino/src/codegenerator/ipf/IpfInst.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfInst.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfInst.cpp (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -30,9 +29,13 @@ // Inst //========================================================================================// -Inst::Inst(InstCode instCode_, Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) { +Inst::Inst(MemoryManager &mm, InstCode instCode, + Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) : + instCode(instCode), + compList(mm), + opndList(mm), + addr(0) { - instCode = instCode_; if(op1 != NULL) opndList.push_back(op1); if(op2 != NULL) opndList.push_back(op2); if(op3 != NULL) opndList.push_back(op3); @@ -43,10 +46,13 @@ //----------------------------------------------------------------------------------------// -Inst::Inst(InstCode instCode_, Completer comp1, - Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) { +Inst::Inst(MemoryManager &mm, InstCode instCode, Completer comp1, + Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) : + instCode(instCode), + compList(mm), + opndList(mm), + addr(0) { - instCode = instCode_; compList.push_back(comp1); if(op1 != NULL) opndList.push_back(op1); if(op2 != NULL) opndList.push_back(op2); @@ -58,10 +64,13 @@ //----------------------------------------------------------------------------------------// -Inst::Inst(InstCode instCode_, Completer comp1, Completer comp2, - Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) { +Inst::Inst(MemoryManager &mm, InstCode instCode, Completer comp1, Completer comp2, + Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) : + instCode(instCode), + compList(mm), + opndList(mm), + addr(0) { - instCode = instCode_; compList.push_back(comp1); compList.push_back(comp2); if(op1 != NULL) opndList.push_back(op1); @@ -74,10 +83,13 @@ //----------------------------------------------------------------------------------------// -Inst::Inst(InstCode instCode_, Completer comp1, Completer comp2, Completer comp3, - Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) { +Inst::Inst(MemoryManager &mm, InstCode instCode, Completer comp1, Completer comp2, Completer comp3, + Opnd *op1, Opnd *op2, Opnd *op3, Opnd *op4, Opnd *op5, Opnd *op6) : + instCode(instCode), + compList(mm), + opndList(mm), + addr(0) { - instCode = instCode_; compList.push_back(comp1); compList.push_back(comp2); compList.push_back(comp3); Index: vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -51,7 +50,7 @@ logName.append(logFileName); ofs = new(mm) ofstream(logName.c_str()); - BbNode *node = (BbNode *)cfg.getEnterNode(); + BbNode *node = (BbNode *)cfg.getEnterNode(); BbNode *succ = node->getLayoutSucc(); printHead(); @@ -170,7 +169,6 @@ *ofs << " fontpath=\"c:\\winnt\\fonts\";" << ::std::endl; *ofs << " node [shape=record,fontname=\"Courier\",fontsize=9];" << ::std::endl; *ofs << " edge [fontname=\"Courier\",fontsize=9];" << ::std::endl; - } //----------------------------------------------------------------------------------------// @@ -336,7 +334,9 @@ string IrPrinter::toString(OpndSet &opndSet) { ostringstream oss; - OpndVector opndVector(opndSet.begin(), opndSet.end()); + MemoryManager mml(1024, ""); + OpndVector opndVector(mml); + opndVector.insert(opndVector.begin(), opndSet.begin(), opndSet.end()); sort(opndVector.begin(), opndVector.end(), ptr_fun(greaterOpnd)); return toString(opndVector); @@ -347,7 +347,9 @@ string IrPrinter::toString(RegOpndSet &opndSet) { ostringstream oss; - OpndVector opndVector(opndSet.begin(), opndSet.end()); + MemoryManager mml(1024, ""); + OpndVector opndVector(mml); + opndVector.insert(opndVector.begin(), opndSet.begin(), opndSet.end()); sort(opndVector.begin(), opndVector.end(), ptr_fun(greaterOpnd)); return toString(opndVector); Index: vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfRuntimeSupport.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$ * */ @@ -43,26 +42,29 @@ // TryRegion //========================================================================================// -TryRegion::TryRegion(Byte *startAddr_, - Byte *endAddr_, - Byte *handlerAddr_, - ObjectType *exceptionType_, - bool isExceptionObjDead_) : - startAddr(startAddr_), - endAddr(endAddr_), - handlerAddr(handlerAddr_), - exceptionType(exceptionType_), - isExceptionObjDead(isExceptionObjDead_) { +TryRegion::TryRegion(Byte *startAddr, + Byte *endAddr, + Byte *handlerAddr, + ObjectType *exceptionType, + bool isExceptionObjDead) : + startAddr(startAddr), + endAddr(endAddr), + handlerAddr(handlerAddr), + exceptionType(exceptionType), + isExceptionObjDead(isExceptionObjDead) { } //========================================================================================// // RuntimeSupport //========================================================================================// -RuntimeSupport::RuntimeSupport(Cfg &cfg_, CompilationInterface &compilationInterface_) : - mm(cfg_.getMM()), - cfg(cfg_), - compilationInterface(compilationInterface_) { +RuntimeSupport::RuntimeSupport(Cfg &cfg, CompilationInterface &compilationInterface) : + mm(cfg.getMM()), + cfg(cfg), + compilationInterface(compilationInterface), + tryRegions(mm), + safePoints(mm), + mptr2def(mm) { opndManager = cfg.getOpndManager(); } @@ -95,7 +97,7 @@ IPF_LOG << " stack info size (bytes): " << stackInfoSize << endl; IPF_LOG << endl << " Make Root Seet Info" << endl; - Uint32Vector rootSetInfo; + Uint32Vector rootSetInfo(mm); makeRootSetInfo(rootSetInfo); uint32 rootSetInfoSize = ROOT_SET_HEADER_SIZE + rootSetInfo.size() * sizeof(uint32); IPF_LOG << " GC root set info size (bytes): " << rootSetInfoSize << endl; @@ -258,7 +260,7 @@ void RuntimeSupport::buildRootSet() { NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); - RegOpndSet liveSet; + RegOpndSet liveSet(mm); for (uint16 i=0; ifirst) << "->"; IPF_LOG << IrPrinter::toString(it->second.base) << endl; } } - IPF_LOG << " Safe point list:" << endl; + IPF_LOG << endl << " Safe point list" << endl; // set mptr->base relations (vector SafePoint.alivePtrs will contain base after each mptr) // and extend bases live ranges for (uint16 i=0; igetInsts(); - Inst *newInst = new(mm) Inst(INST_MOV, commonBase, oldBase); + Inst *newInst = new(mm) Inst(mm, INST_MOV, commonBase, oldBase); InstIterator pos = find(insts.begin(), insts.end(), inst); if (LOG_ON) if (pos == insts.end()) IPF_ERR << endl; Index: vm/jitrino/src/codegenerator/ipf/IpfType.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfType.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfType.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$ * */ Index: vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (working copy) @@ -17,7 +17,6 @@ /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin - * @version $Revision$ * */ @@ -25,6 +24,7 @@ #include "IpfIrPrinter.h" #include "IpfOpndManager.h" #include "IpfLiveAnalyzer.h" +#include namespace Jitrino { namespace IPF { @@ -35,9 +35,11 @@ // RegisterAllocator //========================================================================================// -RegisterAllocator::RegisterAllocator(Cfg &cfg_) : - mm(cfg_.getMM()), - cfg(cfg_) { +RegisterAllocator::RegisterAllocator(Cfg &cfg) : + mm(cfg.getMM()), + cfg(cfg), + allocSet(mm), + liveSet(mm) { opndManager = cfg.getOpndManager(); } @@ -46,160 +48,198 @@ void RegisterAllocator::allocate() { - IPF_LOG << endl << " Build Interference Matrix" << endl << endl; + IPF_LOG << endl << " Build Interference Matrix" << endl; buildInterferenceMatrix(); - makeInterferenceMatrixSymmetric(); + removeSelfDep(); - IPF_LOG << endl << " Remove Preassigned Opnds" << endl; - removePreassignedOpnds(); - IPF_LOG << endl << " Assign Locations" << endl; assignLocations(); + + IPF_LOG << endl << " Remove Usless \"mov\" Instructions" << endl; + removeSameRegMoves(); } //----------------------------------------------------------------------------------------// +// 1. for each opnd build list of opnds which alive during live range of the opnd (RegOpnd::depOpnds) +// 2. build list of opnds which need allocation (allocSet) void RegisterAllocator::buildInterferenceMatrix() { NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); + for(uint16 i=0; iisBb() == false) continue; // ignore non BB nodes - IPF_LOG << " node" << nodes[i]->getId(); - if(nodes[i]->isBb() == false) { // ignore non BB nodes - IPF_LOG << " node is not BB - ignore" << endl; - continue; - } + liveSet.clear(); // clear live set + nodes[i]->mergeOutLiveSets(liveSet); // put in the live set merged live sets of successors - liveSet.clear(); // clear live set - nodes[i]->mergeOutLiveSets(liveSet); // put in the live set merged live sets of successors - IPF_LOG << " live set: " << IrPrinter::toString(liveSet) << endl; - BbNode *node = (BbNode *)nodes[i]; uint32 execCounter = node->getExecCounter(); InstIterator currInst = node->getInsts().end()-1; InstIterator firstInst = node->getInsts().begin()-1; - for(; currInst>firstInst; currInst--) { + for (; currInst>firstInst; currInst--) { Inst *inst = *currInst; - uint16 numDst = inst->getNumDst(); // number of dst opnds (qp has index 0) - OpndVector& opnds = inst->getOpnds(); // get inst's opnds + uint16 numDst = inst->getNumDst(); // number of dst opnds (qp has index 0) + OpndVector& opnds = inst->getOpnds(); // get inst's opnds - LiveAnalyzer::defOpnds(liveSet, inst); // remove dst opnds from live set - checkCallSite(inst); // if currInst is "call" - all alive opnds cross call site - for(uint16 i=1; i<=numDst; i++) { // for each dst opnd - updateAllocSet(opnds[i], execCounter); // insert in allocSet and add live set in dep list + checkCoalescing(execCounter, inst); + + LiveAnalyzer::defOpnds(liveSet, inst); // remove dst opnds from live set + checkCallSite(inst); // if currInst is "call" - all alive opnds cross call site + for(uint16 i=1; i<=numDst; i++) { // for each dst opnd + updateAllocSet(opnds[i], execCounter); // insert in allocSet and add live set in dep list } - LiveAnalyzer::useOpnds(liveSet, inst); // add src opnds in live set - updateAllocSet(opnds[0], execCounter); // insert in allocSet pq opnd and add alive qps in dep list - for(uint16 i=numDst+1; igetInstCode() != INST_MOV) return; // if inst is not "mov" - ignore + + Opnd *qp = inst->getOpnd(0); // get dst opnd of mov inst + Opnd *dst = inst->getOpnd(1); // get dst opnd of mov inst + Opnd *src = inst->getOpnd(2); // get src opnd of mov inst + + if (qp->getValue() != 0) return; // if it is not p0 - ignore + if (dst->getOpndKind() != src->getOpndKind()) return; // if opnds have different reg types - ignore + if (src->isConstant() == true) return; // if src is constant (r0, f1 ...) - ignore + + RegOpnd *dst_ = (RegOpnd *)dst; + RegOpnd *src_ = (RegOpnd *)src; + dst_->addCoalesceCand(execCounter, src_); + src_->addCoalesceCand(execCounter, dst_); +} + +//----------------------------------------------------------------------------------------// // 1. Remove opnd dependency on itself -// 2. Make dependency matrix symmetric +// 2. Log out opnd dependencis -void RegisterAllocator::makeInterferenceMatrixSymmetric() { +void RegisterAllocator::removeSelfDep() { - for(RegOpndSetIterator it1=allocSet.begin(); it1!=allocSet.end(); it1++) { - RegOpnd *opnd = *it1; - opnd->getDepOpnds().erase(opnd); - RegOpndSet &depOpnds = opnd->getDepOpnds(); - for(RegOpndSetIterator it2=depOpnds.begin(); it2!=depOpnds.end(); it2++) { - (*it2)->insertDepOpnd(opnd); - } + for(RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) { + (*it)->getDepOpnds().erase(*it); } if(LOG_ON) { - IPF_LOG << endl << " Opnds dependensies: " << endl; + IPF_LOG << endl << " Opnd dependensies " << endl; for(RegOpndSetIterator it=allocSet.begin(); it!=allocSet.end(); it++) { RegOpnd *opnd = *it; IPF_LOG << " " << setw(4) << left << IrPrinter::toString(opnd) << " depends on: "; - RegOpndSet &depOpnds = opnd->getDepOpnds(); - IPF_LOG << IrPrinter::toString(depOpnds) << endl; + IPF_LOG << IrPrinter::toString(opnd->getDepOpnds()) << endl; } } } //----------------------------------------------------------------------------------------// -// 1. Creates out arg opngs list -// 2. Iterate through opnds having preassigned regs and notify their dep opnds that the reg -// has already been used -// 3. Remove opnds having preassigned regs from allocation cands list - -void RegisterAllocator::removePreassignedOpnds() { - - for(RegOpndSetIterator it1=allocSet.begin(); it1!=allocSet.end();) { - - RegOpnd *opnd = *it1; - int32 location = opnd->getLocation(); - - // if opnd does not have preassigned location - ignore - if(location == LOCATION_INVALID) { it1++; continue; } - - RegOpndSet& depOpnds = opnd->getDepOpnds(); // get opnds that depend on current one - for(RegOpndSetIterator it2=depOpnds.begin(); it2!=depOpnds.end(); it2++) { - (*it2)->markRegBusy(location); - } - - // remove opnd - IPF_LOG << " remove " << IrPrinter::toString(opnd) << endl; - it1++; - allocSet.erase(opnd); - } -} - -//----------------------------------------------------------------------------------------// // 1. Sort opnd list by Spill Cost // 2. Assign locations to all not allocated opnds void RegisterAllocator::assignLocations() { - RegOpndVector opndVector(allocSet.begin(), allocSet.end()); // create vector of opns to be allocated + RegOpndVector opndVector(mm); + opndVector.insert(opndVector.begin(), allocSet.begin(), allocSet.end()); // create vector of opns to be allocated sort(opndVector.begin(), opndVector.end(), greaterSpillCost); // sort them by Spill Cost for (uint16 i=0; igetLocation() != LOCATION_INVALID) continue; // opnd has already had location + IPF_LOG << " " << left << setw(5) << IrPrinter::toString(opnd); - opndManager->assignLocation(opnd); // assign location for current opnd + assignLocation(opnd); // assign location for current opnd 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 - - RegOpndSet &depOpnds = opnd->getDepOpnds(); - int32 regNum = opnd->getLocation(); - for (RegOpndSetIterator it=depOpnds.begin(); it!=depOpnds.end(); it++) { - (*it)->markRegBusy(regNum); // notify all dep opnds that they can not use this reg + } +} + +//----------------------------------------------------------------------------------------// +// remove useless move insts: +// mov r8 = r8 + +void RegisterAllocator::removeSameRegMoves() { + + NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); + for(uint16 i=0; iisBb() == false) continue; // ignore non BB nodes + + BbNode *node = (BbNode *)nodes[i]; + InstVector &insts = node->getInsts(); + for (InstVector::iterator it=insts.begin(); it!=insts.end();) { + Inst *inst = *it; + if (inst->getInstCode() != INST_MOV) { it++; continue; } + Opnd *dst = inst->getOpnd(1); // get dst opnd of mov inst + Opnd *src = inst->getOpnd(2); // get src opnd of mov inst + if (dst->getOpndKind() != src->getOpndKind()) { it++; continue; } // if opnds have different reg types - ignore + if (dst->getValue() != src->getValue()) { it++; continue; } // if opnds allocated on different regs - ignore + + it = insts.erase(it); + IPF_LOG << " node" << left << setw(4) << node->getId() << IrPrinter::toString(inst) << endl; } } } //----------------------------------------------------------------------------------------// +// find and assign location for target opnd -void RegisterAllocator::updateAllocSet(Opnd *opnd, uint32 execCounter) { +void RegisterAllocator::assignLocation(RegOpnd *target) { + + OpndKind opndKind = target->getOpndKind(); + DataKind dataKind = target->getDataKind(); + bool isPreserved = target->getCrossCallSite(); - if (opnd->isReg() == false) return; // imm - it does not need allocation - if (opnd->isMem() == true) return; // mem stack - it does not need allocation - if (opnd->isConstant() == true) return; // constant - it does not need allocation + // build mask of used regs (already assigned opnds) + RegBitSet usedMask; + RegOpndSet &depOpnds = target->getDepOpnds(); + for (RegOpndSet::iterator it=depOpnds.begin(); it!=depOpnds.end(); it++) { + RegOpnd *opnd = *it; + int32 location = opnd->getLocation(); // get location of dep opnd + if (location >= NUM_G_REG) continue; // if opnd is not assigned on reg - continue + usedMask[location] = true; // mark reg busy + } - RegOpnd *regOpnd = (RegOpnd *)opnd; + // try to find opnd to coalesce on + Int2OpndMap &coalesceCands = target->getCoalesceCands(); + for (Int2OpndMap::iterator it=coalesceCands.begin(); it!=coalesceCands.end(); it++) { + RegOpnd *opnd = it->second; + int32 location = opnd->getValue(); + if (location > NUM_G_REG) continue; + if (isPreserved && (opnd->getCrossCallSite()==false)) continue; + if (usedMask[location] == true) continue; + target->setLocation(location); + return; + } + + int32 location = opndManager->newLocation(opndKind, dataKind, usedMask, isPreserved); + target->setLocation(location); // set location +} - regOpnd->incSpillCost(execCounter); // increase opnd spill cost - allocSet.insert(regOpnd); // isert opnd in list for allocation +//----------------------------------------------------------------------------------------// +void RegisterAllocator::updateAllocSet(Opnd *cand_, uint32 execCounter) { + + if (cand_->isReg() == false) return; // imm - it does not need allocation + if (cand_->isMem() == true) return; // mem stack - it does not need allocation + if (cand_->isConstant() == true) return; // constant - it does not need allocation + + RegOpnd *cand = (RegOpnd *)cand_; + cand->incSpillCost(execCounter); // increase opnd spill cost + allocSet.insert(cand); // isert opnd in list for allocation + // add current live set in opnd dep list (they must be placed on different regs) for (RegOpndSetIterator it=liveSet.begin(); it!=liveSet.end(); it++) { - regOpnd->insertDepOpnd(*it); + RegOpnd *opnd = *it; + cand->insertDepOpnd(opnd); // cand depends on curr opnd from live set + opnd->insertDepOpnd(cand); // curr opnd from live set depends on cand } } Index: vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfOpndManager.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$ * */ @@ -241,6 +240,8 @@ p0 = NULL; b0 = NULL; r12 = NULL; + r8 = NULL; + f8 = NULL; tau = NULL; containCall = false; @@ -261,7 +262,7 @@ //----------------------------------------------------------------------------------------// RegOpnd *OpndManager::newRegOpnd(OpndKind opndKind, DataKind dataKind, int32 location) { - return new(mm) RegOpnd(maxOpndId++, opndKind, dataKind, location); + return new(mm) RegOpnd(mm, maxOpndId++, opndKind, dataKind, location); } //----------------------------------------------------------------------------------------// @@ -296,6 +297,8 @@ RegOpnd *OpndManager::getP0() { if(p0 ==NULL) p0 =newRegOpnd(OPND_P_REG, DATA_P, 0); return p0; } RegOpnd *OpndManager::getB0() { if(b0 ==NULL) b0 =newRegOpnd(OPND_B_REG, DATA_I64, 0); return b0; } RegOpnd *OpndManager::getR12() { if(r12==NULL) r12=newRegOpnd(OPND_G_REG, DATA_I64, 12); return r12; } +RegOpnd *OpndManager::getR8() { if(r8 ==NULL) r8 =newRegOpnd(OPND_G_REG, DATA_I64, 8); return r8; } +RegOpnd *OpndManager::getF8() { if(f8 ==NULL) f8 =newRegOpnd(OPND_F_REG, DATA_F, 8); return f8; } RegOpnd *OpndManager::getTau() { if(tau==NULL) tau=newRegOpnd(OPND_INVALID, DATA_INVALID); return tau; } RegOpnd *OpndManager::getR0(RegOpnd *ref) { return newRegOpnd(OPND_G_REG, ref->getDataKind(), 0); } @@ -318,7 +321,8 @@ Opnd *OpndManager::getVtableOffset() { if (vtableOffset == NULL) { - vtableOffset = newImm(compilationInterface.getVTableOffset()); + int64 offset = compilationInterface.getVTableOffset(); + if (offset != 0) vtableOffset = newImm(offset); } return vtableOffset; } @@ -335,7 +339,7 @@ if (heapBase != NULL) { baseValue = (uint64) compilationInterface.getHeapBase(); baseImm = newImm(baseValue); - Inst *inst = new(mm) Inst(INST_MOVL, p0, heapBase, baseImm); + Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, heapBase, baseImm); insts.insert(insts.begin(), inst); IPF_LOG << " HeapBase initialization code inserted" << endl; } @@ -343,27 +347,13 @@ if (vtableBase != NULL) { baseValue = (uint64) compilationInterface.getVTableBase(); baseImm = newImm(baseValue); - Inst *inst = new(mm) Inst(INST_MOVL, p0, vtableBase, baseImm); + Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, vtableBase, baseImm); insts.insert(insts.begin(), inst); IPF_LOG << " VtableBase initialization code inserted" << endl; } } //----------------------------------------------------------------------------------------// -// assign location for opnd - -void OpndManager::assignLocation(RegOpnd *opnd) { - - OpndKind opndKind = opnd->getOpndKind(); - DataKind dataKind = opnd->getDataKind(); - RegBitSet &usedMask = opnd->getBusyRegMask(); - bool isPreserved = opnd->getCrossCallSite(); - - int32 location = newLocation(opndKind, dataKind, usedMask, isPreserved); - opnd->setLocation(location); -} - -//----------------------------------------------------------------------------------------// // tryes to find available location for the opndKind/dataKind taking in account mask of used regs int32 OpndManager::newLocation(OpndKind opndKind, @@ -379,7 +369,7 @@ if (location != LOCATION_INVALID) return location; // if we succeed - return it } // it is preserved location or we failed to find scratch one - location = newPreservReg(opndKind, unusedMask); // try to find preserved register + location = newPreservReg(opndKind, unusedMask); // try to find preserved register if (location != LOCATION_INVALID) return location; // if we succeed - return it // we failed to find available register return newLocSlot(dataKind); // allocate new slot on memory stack @@ -465,7 +455,7 @@ IPF_LOG << " Stack info" << endl; IPF_LOG << " Register: loc=" << locRegSize << " out=" << outRegSize << endl; IPF_LOG << " Memory : loc=" << locMemSize << " out=" << outMemSize << endl; - IPF_LOG << " Method contains call = " << boolalpha << containCall << endl; + IPF_LOG << " Method contains call: " << boolalpha << containCall << endl; } //----------------------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/IpfDce.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfDce.cpp (revision 473173) +++ vm/jitrino/src/codegenerator/ipf/IpfDce.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$ * */ @@ -37,15 +36,11 @@ IPF_LOG << endl; NodeVector &nodes = cfg.search(SEARCH_POST_ORDER); // get postordered node list - for(uint16 i=0; imergeOutLiveSets(currLiveSet); // put in the live set merged live sets of successors - IPF_LOG << " node" << nodes[i]->getId() << endl; -// IPF_LOG << " exit live set: " << IrPrinter::toString(currLiveSet) << endl; - if(nodes[i]->getNodeKind() != NODE_BB) continue; // node does not contain insts - ignore InstVector &insts = ((BbNode *)nodes[i])->getInsts(); @@ -56,15 +51,13 @@ if (isInstDead(*currInst)) { InstIterator inst = currInst--; - removeInst(insts, inst); + IPF_LOG << " node" << nodes[i]->getId(); + IPF_LOG << " dead code - " << IrPrinter::toString(*inst) << endl; + insts.erase(inst); // remove instruction continue; } LiveAnalyzer::updateLiveSet(currLiveSet, *currInst); - -// IPF_LOG << " " << left << setw(46) << IrPrinter::toString(*currInst) << endl; -// IPF_LOG << " live set : " << IrPrinter::toString(currLiveSet) << endl; - currInst--; } } @@ -93,14 +86,5 @@ return true; } -//----------------------------------------------------------------------------------------// -// Remove instruction from inst vector - -void Dce::removeInst(InstVector &insts, InstIterator inst) { - - IPF_LOG << " dead code - " << IrPrinter::toString(*inst) << endl; - insts.erase(inst); // remove instruction -} - } // IPF } // Jitrino