// Process the structure recursively // int32_t TR_ExpressionsSimplification::perform(TR_Structure * str) { if (trace()) traceMsg(comp(), "Analyzing root Structure : %p\n", str); TR_RegionStructure *region; // Only regions can be simplified // if (!(region = str->asRegion())) return 0; TR_RegionStructure::Cursor it(*region); for (TR_StructureSubGraphNode *node = it.getCurrent(); node != 0; node = it.getNext()) { // Too strict /* if ((node->getPredecessors().size() == 1)) { TR::CFGEdge *edge = node->getPredecessors().front(); TR_StructureSubGraphNode *pred = toStructureSubGraphNode(edge->getFrom()); TR_BlockStructure *b = pred->getStructure()->asBlock(); if (b && pred->getSuccessors().size() == 1)) perform(node->getStructure()); } */ perform(node->getStructure()); } // debug only // /* if (region->isNaturalLoop() && (region->getParent() && !region->getParent()->asRegion()->isCanonicalizedLoop())) { traceMsg(comp(), "Loop not canonicalized %x\n", region); } */ TR::Block *entryBlock = region->getEntryBlock(); if (region->isNaturalLoop() && !entryBlock->isCold() && (region->getParent() /* && region->getParent()->asRegion()->isCanonicalizedLoop() */)) { if (trace()) traceMsg(comp(), "Found candidate non cold loop %p for expression elimination\n", region); findAndSimplifyInvariantLoopExpressions(region); } return 1; // Need to specify the cost }
TR_GlobalRegisterNumber OMR::X86::I386::CodeGenerator::pickRegister( TR_RegisterCandidate *rc, TR::Block **allBlocks, TR_BitVector &availableRegisters, TR_GlobalRegisterNumber &highRegisterNumber, TR_LinkHead<TR_RegisterCandidate> *candidates) { if (!self()->comp()->getOption(TR_DisableRegisterPressureSimulation)) { if (self()->comp()->getOption(TR_AssignEveryGlobalRegister)) { // This is not really necessary except for testing purposes. // Conceptually, the common pickRegister code should be free to make // its choices based only on performance considerations, and shouldn't // need to worry about correctness. When SupportsVMThreadGRA is not set, // it is incorrect to choose the VMThread register. Therefore we mask // it out here. // // Having said that, the common code *does* already mask out the // VMThread register for convenience, so under normal circumstances, // this code is redundant. It is only necessary when // TR_AssignEveryGlobalRegister is set. // availableRegisters -= *self()->getGlobalRegisters(TR_vmThreadSpill, self()->comp()->getMethodSymbol()->getLinkageConvention()); } return OMR::CodeGenerator::pickRegister(rc, allBlocks, availableRegisters, highRegisterNumber, candidates); } if ((rc->getSymbol()->getDataType() == TR::Float) || (rc->getSymbol()->getDataType() == TR::Double)) { if (availableRegisters.get(7)) return 7; if (availableRegisters.get(8)) return 8; if (availableRegisters.get(9)) return 9; if (availableRegisters.get(10)) return 10; if (availableRegisters.get(11)) return 11; if (availableRegisters.get(12)) return 12; return -1; } if (!_assignedGlobalRegisters) _assignedGlobalRegisters = new (self()->trStackMemory()) TR_BitVector(self()->comp()->getSymRefCount(), self()->trMemory(), stackAlloc, growable); if (availableRegisters.get(5)) return 5; // esi if (availableRegisters.get(2)) return 2; // ecx static char *dontUseEBXasGPR = feGetEnv("dontUseEBXasGPR"); if (!dontUseEBXasGPR && availableRegisters.get(1)) return 1; #ifdef J9_PROJECT_SPECIFIC TR::RecognizedMethod rm = self()->comp()->getMethodSymbol()->getRecognizedMethod(); if (rm == TR::java_util_HashtableHashEnumerator_hasMoreElements) { if (availableRegisters.get(4)) return 4; // edi if (availableRegisters.get(3)) return 3; // edx } else #endif { int32_t numExtraRegs = 0; int32_t maxRegisterPressure = 0; vcount_t visitCount = self()->comp()->incVisitCount(); TR_BitVectorIterator bvi(rc->getBlocksLiveOnEntry()); int32_t maxFrequency = 0; while (bvi.hasMoreElements()) { int32_t liveBlockNum = bvi.getNextElement(); TR::Block *block = allBlocks[liveBlockNum]; if (block->getFrequency() > maxFrequency) maxFrequency = block->getFrequency(); } int32_t maxStaticFrequency = 0; if (maxFrequency == 0) { bvi.setBitVector(rc->getBlocksLiveOnEntry()); while (bvi.hasMoreElements()) { int32_t liveBlockNum = bvi.getNextElement(); TR::Block *block = allBlocks[liveBlockNum]; TR_BlockStructure *blockStructure = block->getStructureOf(); int32_t blockWeight = 1; if (blockStructure && !block->isCold()) { blockStructure->calculateFrequencyOfExecution(&blockWeight); if (blockWeight > maxStaticFrequency) maxStaticFrequency = blockWeight; } } } bool assigningEDX = false; if (!availableRegisters.get(4) && availableRegisters.get(3)) assigningEDX = true; bool vmThreadUsed = false; bvi.setBitVector(rc->getBlocksLiveOnEntry()); while (bvi.hasMoreElements()) { int32_t liveBlockNum = bvi.getNextElement(); TR::Block *block = allBlocks[liveBlockNum]; _assignedGlobalRegisters->empty(); int32_t numAssignedGlobalRegs = 0; TR_RegisterCandidate *prev; for (prev = candidates->getFirst(); prev; prev = prev->getNext()) { bool gprCandidate = true; if ((prev->getSymbol()->getDataType() == TR::Float) || (prev->getSymbol()->getDataType() == TR::Double)) gprCandidate = false; if (gprCandidate && prev->getBlocksLiveOnEntry().get(liveBlockNum)) { numAssignedGlobalRegs++; if (prev->getDataType() == TR::Int64) numAssignedGlobalRegs++; _assignedGlobalRegisters->set(prev->getSymbolReference()->getReferenceNumber()); } } maxRegisterPressure = self()->estimateRegisterPressure(block, visitCount, maxStaticFrequency, maxFrequency, vmThreadUsed, numAssignedGlobalRegs, _assignedGlobalRegisters, rc->getSymbolReference(), assigningEDX); if (maxRegisterPressure >= self()->getMaximumNumbersOfAssignableGPRs()) break; } // Determine if we can spare any extra registers for this candidate without spilling // in any hot (critical) blocks // if (maxRegisterPressure < self()->getMaximumNumbersOfAssignableGPRs()) numExtraRegs = self()->getMaximumNumbersOfAssignableGPRs() - maxRegisterPressure; //dumpOptDetails("For global register candidate %d reg pressure is %d maxRegs %d numExtraRegs %d\n", rc->getSymbolReference()->getReferenceNumber(), maxRegisterPressure, comp()->cg()->getMaximumNumbersOfAssignableGPRs(), numExtraRegs); if (numExtraRegs > 0) { if (availableRegisters.get(4)) return 4; // edi if (availableRegisters.get(3)) return 3; // edx } } return -1; // -1 ==> don't use a global register }