// TODO: Try to combine the 2 layoutParm functions. int32_t TR::AMD64SystemLinkage::layoutParm( TR::ParameterSymbol *parmSymbol, int32_t &dataCursor, uint16_t &intReg, uint16_t &floatReg, TR::parmLayoutResult &layoutResult) { //AMD64 SysV ABI: if the size of an object is larger than four eightbytes, or it contains unaligned fields, it has class MEMORY. if (parmSymbol->getSize() > 4*AMD64_STACK_SLOT_SIZE) goto LAYOUT_ON_STACK; if (layoutTypeInRegs(parmSymbol->getDataType(), intReg, floatReg, layoutResult)) { layoutResult.abstract |= TR::parmLayoutResult::IN_LINKAGE_REG; if (parmSymbol->getSize() > GPR_REG_WIDTH) layoutResult.abstract |= TR::parmLayoutResult::IN_LINKAGE_REG_PAIR; if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "layout param symbol %p in register\n", parmSymbol); if (!getProperties().getCallerFrameAllocatesSpaceForLinkageRegisters()) return 0; } LAYOUT_ON_STACK: layoutResult.abstract |= TR::parmLayoutResult::ON_STACK; int32_t align = layoutTypeOnStack(parmSymbol->getDataType(), dataCursor, layoutResult); if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "layout param symbol %p on stack\n", parmSymbol); return align; }
void TR_ReachingDefinitions::initializeGenAndKillSetInfo() { // For each block in the CFG build the gen and kill set for this analysis. // Go in treetop order, which guarantees that we see the correct (i.e. first) // evaluation point for each node. // TR::Block *block; int32_t blockNum = 0; bool seenException = false; TR_BitVector defsKilled(getNumberOfBits(), trMemory()->currentStackRegion()); comp()->incVisitCount(); for (TR::TreeTop *treeTop = comp()->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop()) { TR::Node *node = treeTop->getNode(); if (node->getOpCodeValue() == TR::BBStart) { block = node->getBlock(); blockNum = block->getNumber(); seenException = false; if (traceRD()) traceMsg(comp(), "\nNow generating gen and kill information for block_%d\n", blockNum); continue; } #if DEBUG if (node->getOpCodeValue() == TR::BBEnd && traceRD()) { traceMsg(comp(), " Block %d:\n", blockNum); traceMsg(comp(), " Gen set "); if (_regularGenSetInfo[blockNum]) _regularGenSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Kill set "); if (_regularKillSetInfo[blockNum]) _regularKillSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Exception Gen set "); if (_exceptionGenSetInfo[blockNum]) _exceptionGenSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); traceMsg(comp(), "\n Exception Kill set "); if (_exceptionKillSetInfo[blockNum]) _exceptionKillSetInfo[blockNum]->print(comp()); else traceMsg(comp(), "{}"); continue; } #endif initializeGenAndKillSetInfoForNode(node, defsKilled, seenException, blockNum, NULL); if (!seenException && treeHasChecks(treeTop)) seenException = true; } }
bool TR_LocalLiveRangeReduction::verifyRefInfo(List<TR::Node> *verifier,List<TR::Node> *refList) { ListIterator<TR::Node> listIt(refList); TR::Node *node = NULL; for ( node = listIt.getFirst(); node != NULL; node = listIt.getNext()) { if (verifier->find(node)) verifier->remove(node); else { if (trace()) traceMsg(comp(),"LocalLiveRangeReduction:node %p should not have beed in the List\n",node); return false; } } if (!verifier->isEmpty()) { if (trace()) traceMsg(comp(),"LocalLiveRangeReduction: there are nodes that should have been in the List\n"); return false; } return true; }
void TR::AMD64SystemLinkage::setUpStackSizeForCallNode(TR::Node* node) { const TR::X86LinkageProperties &properties = getProperties(); uint16_t intReg = 0, floatReg = 0; // AMD64 SysV ABI: The end of the input argument area shall be aligned on a 16 (32, if __m256 is passed on stack) byte boundary. In other words, the value (%rsp + 8) is always a multiple of 16 (32) when control is transferred to the function entry point. int32_t alignment = AMD64_DEFAULT_STACK_ALIGNMENT; int32_t sizeOfOutGoingArgs = 0; if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "setUpStackSizeForCallNode for call node %p\n", node); for (int32_t i= node->getFirstArgumentIndex(); i<node->getNumChildren(); ++i) { TR::parmLayoutResult fakeParm; TR::Node *parmNode = node->getChild(i); int32_t parmAlign = layoutParm(parmNode, sizeOfOutGoingArgs, intReg, floatReg, fakeParm); if (parmAlign == 32) alignment = 32; } if (sizeOfOutGoingArgs > cg()->getLargestOutgoingArgSize()) { cg()->setLargestOutgoingArgSize(sizeOfOutGoingArgs); if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "setUpStackSizeForCallNode setLargestOutgoingArgSize %d(for call node %p)\n", sizeOfOutGoingArgs, node); } if (alignment > _properties.getOutgoingArgAlignment()) { _properties.setOutgoingArgAlignment(alignment); if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "setUpStackSizeForCallNode setOutgoingArgAlignment %d(for call node %p)\n", alignment, node); } }
void TR_ExpressionsSimplification::setStoreMotionCandidates(TR::Node *node, TR::TreeTop *tt) { // Must be a store node, of any type but not holding a monitor object // if (node->getOpCode().isStore() && !node->getSymbol()->isStatic() && !node->getSymbol()->holdsMonitoredObject()) { if (trace()) traceMsg(comp(), "Node %p: The opcode is a non-static, non-monitor object store\n", node); for (int32_t i = 0; i < node->getNumChildren(); i++) { if (!_currentRegion->isExprInvariant(node->getChild(i))) { if (trace()) traceMsg(comp(), "Node %p: The store is not loop-invariant due to child %p\n", node, node->getChild(i)); return; } } // If store's operands are loop-invariant if (trace()) { traceMsg(comp(), "Node %p: The store's operands are all loop-invariant, adding candidate\n", node); traceMsg(comp(), "Node %p: - value of isExprInvariant for the store itself is %s\n", node, _currentRegion->isExprInvariant(node) ? "true" : "false"); } _candidateTTs->add(tt); } }
void TR_LocalLiveRangeReduction::printRefInfo(TR_TreeRefInfo *treeRefInfo) { if (trace()) { TR::Node *n; ListIterator<TR::Node> lit(treeRefInfo->getFirstRefNodesList()); traceMsg(comp(),"[%p]:F={",treeRefInfo->getTreeTop()->getNode()); for (n = lit.getFirst(); n != NULL; n = lit.getNext()) traceMsg(comp(),"%p ",n); traceMsg(comp(),"},M={"); lit.set(treeRefInfo->getMidRefNodesList()); for (n = lit.getFirst(); n != NULL; n = lit.getNext()) traceMsg(comp(),"%p ",n); traceMsg(comp(),"},L={"); lit.set(treeRefInfo->getLastRefNodesList()); for (n = lit.getFirst(); n != NULL; n = lit.getNext()) traceMsg(comp(),"%p ",n); traceMsg(comp(),"}\n"); if (treeRefInfo->getUseSym() && treeRefInfo->getDefSym()) { traceMsg(comp(),"[%p]:use = ",treeRefInfo->getTreeTop()->getNode()); treeRefInfo->getUseSym()->print(comp()); traceMsg(comp()," def = "); treeRefInfo->getDefSym()->print(comp()); traceMsg(comp(),"\n"); } } }
const int32_t TR_LoadExtensions::setExtensionPreference(TR::Node* load, TR::Node* conversion) { int32_t result; if (conversion->isZeroExtension() || conversion->getOpCode().isUnsigned()) { if (trace()) { traceMsg(comp(), "\t\tCounting unsigned load %s [%p] under %s [%p]\n", load->getOpCode().getName(), load, conversion->getOpCode().getName(), conversion); } // i.e. TR::bu2i || TR::iu2l result = --(*loadExtensionPreference)[load]; } else { if (trace()) { traceMsg(comp(), "\t\tCounting signed load %s [%p] under %s [%p]\n", load->getOpCode().getName(), load, conversion->getOpCode().getName(), conversion); } // i.e. TR::i2l || TR::b2i result = ++(*loadExtensionPreference)[load]; } return result; }
void TR_RegisterAnticipatability::analyzeTreeTopsInBlockStructure(TR_BlockStructure *blockStructure) { int32_t blockNum = blockStructure->getBlock()->getNumber(); // save the outSetInfo for later use // copyFromInto(_regularInfo, _outSetInfo[blockNum]); // now compose the exception info into the outSet // for this block // compose(_regularInfo, _exceptionInfo); compose(_outSetInfo[blockNum], _exceptionInfo); // compute the _inSet = _outSet + RUSE // *_regularInfo |= *_registerUsageInfo[blockNum]; *_exceptionInfo |= *_registerUsageInfo[blockNum]; //FIXME: is this too conservative? if (comp()->getOption(TR_TraceShrinkWrapping)) { traceMsg(comp(), "Normal info of block_%d : ", blockNum); _regularInfo->print(comp()); traceMsg(comp(), "\n"); } }
void TR::RegDepCopyRemoval::makeFreshCopy(TR_GlobalRegisterNumber reg) { RegDepInfo &dep = getRegDepInfo(reg); if (!performTransformation(comp(), "%schange %s in GlRegDeps n%un to an explicit copy of n%un\n", optDetailString(), registerName(reg), _regDeps->getGlobalIndex(), dep.value->getGlobalIndex())) return; // Split the block at fallthrough if necessary to avoid putting copies // between branches and BBEnd. TR::Node *curNode = _treetop->getNode(); if (curNode->getOpCodeValue() == TR::BBEnd) { TR::Block *curBlock = curNode->getBlock(); if (curBlock->getLastRealTreeTop() != curBlock->getLastNonControlFlowTreeTop()) { TR::Block *fallthrough = curBlock->getNextBlock(); fallthrough = curBlock->splitEdge(curBlock, fallthrough, comp()); TR_ASSERT(curBlock->getNextBlock() == fallthrough, "bad block placement from splitEdge\n"); fallthrough->setIsExtensionOfPreviousBlock(); _treetop = fallthrough->getExit(); TR::Node *newNode = _treetop->getNode(); newNode->setChild(0, _regDeps); newNode->setNumChildren(1); curNode->setNumChildren(0); if (trace()) traceMsg(comp(), "\tsplit fallthrough edge to insert copy, created block_%d\n", fallthrough->getNumber()); } } // Make and insert the copy TR::Node *copyNode = NULL; if (dep.value->getOpCode().isLoadConst()) { // No need to depend on the other register. // TODO heuristic for whether this is really better than a reg-reg move? generateRegcopyDebugCounter("const-remat"); copyNode = TR::Node::create(dep.value->getOpCodeValue(), 0); copyNode->setConstValue(dep.value->getConstValue()); } else { generateRegcopyDebugCounter("fresh-copy"); copyNode = TR::Node::create(TR::PassThrough, 1, dep.value); copyNode->setCopyToNewVirtualRegister(); } TR::Node *copyTreetopNode = TR::Node::create(TR::treetop, 1, copyNode); _treetop->insertBefore(TR::TreeTop::create(comp(), copyTreetopNode)); if (trace()) traceMsg(comp(), "\tcopy is n%un\n", copyNode->getGlobalIndex()); updateSingleRegDep(reg, copyNode); }
// 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 }
void createGuardSiteForRemovedGuard(TR::Compilation *comp, TR::Node *ifNode) { #ifdef J9_PROJECT_SPECIFIC if (comp->cg()->needGuardSitesEvenWhenGuardRemoved() && ifNode->isTheVirtualGuardForAGuardedInlinedCall()) { TR_VirtualGuard *virtualGuard = comp->findVirtualGuardInfo(ifNode); if (virtualGuard->getKind() == TR_HCRGuard) { if (comp->getOption(TR_TraceReloCG)) traceMsg(comp, "createGuardSiteForRemovedGuard: removing HCRGuard, no need to add AOTNOPsite, node %p\n", ifNode); return; } if (virtualGuard->getKind() == TR_BreakpointGuard) { if (comp->getOption(TR_TraceReloCG)) traceMsg(comp, "createGuardSiteForRemovedGuard: removing BreakpointGuard, no need to add AOTNOPsite, node %p\n", ifNode); return; } TR_VirtualGuardKind removedGuardKind; switch (virtualGuard->getKind()) { case TR_ProfiledGuard: removedGuardKind = TR_RemovedProfiledGuard; TR_ASSERT(ifNode->isProfiledGuard(), "guard for profiled guard has unexpected kind"); break; case TR_InterfaceGuard: removedGuardKind = TR_RemovedInterfaceGuard; TR_ASSERT(ifNode->isInterfaceGuard(), "guard for interface guard has unexpected kind"); break; case TR_NonoverriddenGuard: case TR_DirectMethodGuard: removedGuardKind = TR_RemovedNonoverriddenGuard; TR_ASSERT(ifNode->isNonoverriddenGuard(), "guard for nonoverridden guard has unexpected kind"); break; default: TR_ASSERT(false, "removed virtual guard type %d on node %p not supported yet.", virtualGuard->getKind(), ifNode); break; }; TR_AOTGuardSite *site = comp->addAOTNOPSite(); site->setLocation(NULL); site->setType(removedGuardKind); site->setGuard(virtualGuard); site->setNode(NULL); if (comp->getOption(TR_TraceAll)) traceMsg(comp, "createGuardSiteForRemovedGuard: removedGuardKind %d, removedGurad %p, _callNode %p, _guardNode %p, _thisClass %p, _calleeIndex %d, _byteCodeIndex %d, addedAOTNopSite %p\n", removedGuardKind, virtualGuard, virtualGuard->getCallNode(), virtualGuard->getGuardNode(), virtualGuard->getThisClass(), virtualGuard->getCalleeIndex(), virtualGuard->getByteCodeIndex(), site); } #endif }
void TR_LocalLiveRangeReduction::printOnVerifyError(TR_TreeRefInfo *optRefInfo,TR_TreeRefInfo *verifier ) { if (trace()) { traceMsg(comp(),"from opt:"); printRefInfo(optRefInfo); traceMsg(comp(),"verifyer:"); printRefInfo(verifier); comp()->dumpMethodTrees("For verifying\n"); comp()->incVisitCount(); } }
void TR_ExpressionsSimplification::removeCandidate(TR::Node *node, TR::TreeTop* tt) { if (node->getVisitCount() == _visitCount) return; node->setVisitCount(_visitCount); if (trace()) traceMsg(comp(), "Looking at Node [%p]\n", node); ListIterator<TR::TreeTop> candidateTTs(_candidateTTs); for (TR::TreeTop *candidateTT = candidateTTs.getFirst(); candidateTT; candidateTT = candidateTTs.getNext()) { if (tt != candidateTT && node->getOpCode().hasSymbolReference() && candidateTT->getNode()->mayKill(true).contains(node->getSymbolReference(), comp())) { if (trace()) traceMsg(comp(), "Removing candidate %p which has aliases in the loop\n", candidateTT->getNode()); _candidateTTs->remove(candidateTT); continue; } } bool hasSupportedChildren = true; // Process the children as well // for (int32_t i = 0; i < node->getNumChildren(); i++) { removeCandidate(node->getChild(i), tt); // candidates child expressions must be invariant and supported. Here we determine if they are supported. if (!_supportedExpressions->get(node->getChild(i)->getGlobalIndex())) { hasSupportedChildren = false; } } if (hasSupportedChildren && isSupportedNodeForExpressionSimplification(node)) { _supportedExpressions->set(node->getGlobalIndex()); } else { if (trace()) traceMsg(comp(), " Node %p is unsupported expression because %s\n", node, !hasSupportedChildren ? "it has unsupported children" : "it is itself unsupported"); } }
void TR::AMD64ABILinkage::mapIncomingParms( TR::ResolvedMethodSymbol *method, uint32_t &stackIndex) { ListIterator<TR::ParameterSymbol> parameterIterator(&method->getParameterList()); TR::ParameterSymbol *parmCursor = parameterIterator.getFirst(); if (!parmCursor) return; if (parmCursor->getLinkageRegisterIndex() < 0) { copyLinkageInfoToParameterSymbols(); } // 1st: handle parameters which are passed through stack // TR::X86SystemLinkage::mapIncomingParms(method); // 2nd: handle parameters which are passed through linkage registers, but are // not assigned any register after RA (or say, by their first usage point, // a MOV is needed to load it from stack to register). // // AMD64 SysV ABI says that: a parameter is placed either in registers or // pushed on the stack, but can't take both. So, for parms passed through // linkage registers but don't have physical registers assigned after RA, // we will allocate stack space in local variable region. // for (parmCursor = parameterIterator.getFirst(); parmCursor; parmCursor = parameterIterator.getNext()) { if ((parmCursor->getLinkageRegisterIndex() >= 0) && (parmCursor->getAllocatedIndex() < 0 || hasToBeOnStack(parmCursor))) { uint32_t align = getAlignment(parmCursor->getDataType()); uint32_t alignMinus1 = (align <= AMD64_STACK_SLOT_SIZE) ? (AMD64_STACK_SLOT_SIZE - 1) : (align - 1); uint32_t pos = -stackIndex; pos += parmCursor->getSize(); pos = (pos + alignMinus1) & (~alignMinus1); stackIndex = -pos; parmCursor->setParameterOffset(stackIndex); if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "mapIncomingParms setParameterOffset %d for param symbol (reg param without home location) %p, hasToBeOnStack() %d\n", parmCursor->getParameterOffset(), parmCursor, hasToBeOnStack(parmCursor)); } else if (parmCursor->getLinkageRegisterIndex() >=0 && parmCursor->getAllocatedIndex() >= 0) { //parmCursor->setDontHaveStackSlot(0); // this is a hack , so as we could print stack layout table in createPrologue if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "mapIncomingParms no need to set parm %p, for it has got register %d assigned\n", parmCursor, parmCursor->getAllocatedIndex()); } } }
void TR::ValidateLivenessBoundaries::updateNodeState(TR::Node *node, TR::NodeSideTable<TR::NodeState> &nodeStates, TR::LiveNodeWindow &liveNodes) { TR::NodeState &state = nodeStates[node]; if (node->getReferenceCount() == state._futureReferenceCount) { /* First occurrence -- do some bookkeeping */ if (node->getReferenceCount() == 0) { TR::checkILCondition(node, node->getOpCode().isTreeTop(), comp(), "Only nodes with isTreeTop opcodes can have refcount == 0"); } else { liveNodes.add(node); } } if (liveNodes.contains(node)) { TR::checkILCondition(node, state._futureReferenceCount >= 1, comp(), "Node already has reference count 0"); if (--state._futureReferenceCount == 0) { liveNodes.remove(node); } } else { TR::checkILCondition(node, node->getOpCode().isTreeTop(), comp(), "Node has already gone dead"); } if (TR::isILValidationLoggingEnabled(comp())) { if (!liveNodes.isEmpty()) { traceMsg(comp(), " -- Live nodes: {"); char *separator = ""; for (TR::LiveNodeWindow::Iterator lnwi(liveNodes); lnwi.currentNode(); ++lnwi) { traceMsg(comp(), "%sn%dn", separator, lnwi.currentNode()->getGlobalIndex()); separator = ", "; } traceMsg(comp(), "}\n"); } } }
void TR_ExpressionsSimplification::removeUncertainBlocks(TR_RegionStructure* region, List<TR::Block> *candidateBlocksList) { // Examine the top region block first // TR::Block *entryBlock = _currentRegion->getEntryBlock(); ListIterator<TR::Block> blocks; blocks.set(candidateBlocksList); if (trace()) traceMsg(comp(), "Number of blocks %d, entry block number %d\n", candidateBlocksList->getSize(), entryBlock->getNumber()); for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext()) { TR::CFGNode *cfgNode = block; if (!(cfgNode->getExceptionSuccessors().empty()) || blockHasCalls(block, comp())) { if (trace()) traceMsg(comp(), "An exception can be thrown from block_%d. Removing all the blocks, since we cannot know the number of iterations.\n", block->getNumber()); candidateBlocksList->deleteAll(); break; } } TR_PostDominators postDominators(comp()); if (postDominators.isValid()) { postDominators.findControlDependents(); for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext()) { if (postDominators.dominates(block, entryBlock) == 0) { candidateBlocksList->remove(block); if (trace()) traceMsg(comp(), "Block_%d is not guaranteed to be executed at least once. Removing it from the list.\n", block->getNumber()); } } } else { if (trace()) traceMsg(comp(), "There is no post dominators information. Removing all the blocks.\n"); for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext()) { candidateBlocksList->remove(block); if (trace()) traceMsg(comp(), "Block_%d is removed from the list\n", block->getNumber()); } } }
void TR::ILValidator::updateNodeState(Location &newLocation) { TR::Node *node = newLocation.currentNode(); NodeState &state = _nodeStates[node]; if (node->getReferenceCount() == state._futureReferenceCount) { // First occurrence -- do some bookkeeping // if (node->getReferenceCount() == 0) { validityRule(newLocation, node->getOpCode().isTreeTop(), "Only nodes with isTreeTop opcodes can have refcount == 0"); } else { _liveNodes.add(node); } } if (_liveNodes.contains(node)) { validityRule(newLocation, state._futureReferenceCount >= 1, "Node already has reference count 0"); if (--state._futureReferenceCount == 0) { _liveNodes.remove(node); } } else { validityRule(newLocation, node->getOpCode().isTreeTop(), "Node has already gone dead"); } if (isLoggingEnabled()) { static const char *traceLiveNodesDuringValidation = feGetEnv("TR_traceLiveNodesDuringValidation"); if (traceLiveNodesDuringValidation && !_liveNodes.isEmpty()) { traceMsg(comp(), " -- Live nodes: {"); char *separator = ""; for (LiveNodeWindow::Iterator lnwi(_liveNodes); lnwi.currentNode(); ++lnwi) { traceMsg(comp(), "%sn%dn", separator, lnwi.currentNode()->getGlobalIndex()); separator = ", "; } traceMsg(comp(), "}\n"); } } }
TR::Register* OMR::X86::TreeEvaluator::SIMDloadEvaluator(TR::Node* node, TR::CodeGenerator* cg) { TR::MemoryReference* tempMR = generateX86MemoryReference(node, cg); tempMR = ConvertToPatchableMemoryReference(tempMR, node, cg); TR::Register* resultReg = cg->allocateRegister(TR_VRF); TR_X86OpCodes opCode = BADIA32Op; switch (node->getSize()) { case 16: opCode = MOVDQURegMem; break; default: if (cg->comp()->getOption(TR_TraceCG)) traceMsg(cg->comp(), "Unsupported fill size: Node = %p\n", node); TR_ASSERT(false, "Unsupported fill size"); break; } TR::Instruction* instr = generateRegMemInstruction(opCode, node, resultReg, tempMR, cg); if (node->getOpCode().isIndirect()) cg->setImplicitExceptionPoint(instr); node->setRegister(resultReg); tempMR->decNodeReferenceCounts(cg); return resultReg; }
TR::Node * TR_ExpressionsSimplification::ixorinegSimplifier(TR::Node *node, LoopInfo* loopInfo, bool *removeOnly) { TR::Node *newNode = 0; *removeOnly = false; if (loopInfo->getBoundaryNode()) { if (trace()) traceMsg(comp(), "Loop has a non constant boundary, but this case is not taken care of\n"); } else { if (loopInfo->getNumIterations() > 0) { newNode = node; if (loopInfo->getNumIterations() % 2 == 0) { *removeOnly = true; } } } return newNode; }
TR::Register* OMR::X86::TreeEvaluator::SIMDstoreEvaluator(TR::Node* node, TR::CodeGenerator* cg) { TR::Node* valueNode = node->getChild(node->getOpCode().isIndirect() ? 1 : 0); TR::MemoryReference* tempMR = generateX86MemoryReference(node, cg); tempMR = ConvertToPatchableMemoryReference(tempMR, node, cg); TR::Register* valueReg = cg->evaluate(valueNode); TR_X86OpCodes opCode = BADIA32Op; switch (node->getSize()) { case 16: opCode = MOVDQUMemReg; break; default: if (cg->comp()->getOption(TR_TraceCG)) traceMsg(cg->comp(), "Unsupported fill size: Node = %p\n", node); TR_ASSERT(false, "Unsupported fill size"); break; } TR::Instruction* instr = generateMemRegInstruction(opCode, node, tempMR, valueReg, cg); cg->decReferenceCount(valueNode); tempMR->decNodeReferenceCounts(cg); if (node->getOpCode().isIndirect()) cg->setImplicitExceptionPoint(instr); return NULL; }
void TR::RegDepCopyRemoval::selectNodesToReuse(TR::NodeChecklist &usedNodes) { for (TR_GlobalRegisterNumber reg = _regBegin; reg < _regEnd; reg++) { RegDepInfo &dep = getRegDepInfo(reg); if (dep.state != REGDEP_UNDECIDED) continue; NodeChoice &prevChoice = getNodeChoice(reg); if (dep.value != prevChoice.original) continue; // can't reuse // Reuse our previous choice! if (trace()) traceMsg(comp(), "\t%s: prefer to reuse previous choice n%un\n", registerName(reg), prevChoice.selected->getGlobalIndex()); TR_ASSERT(!usedNodes.contains(prevChoice.selected), "attempted to reuse the same node more than once\n"); if (prevChoice.selected == dep.value) { dep.state = REGDEP_NODE_ORIGINAL; usedNodes.add(dep.value); } else { dep.state = REGDEP_NODE_REUSE_COPY; } } }
void CTraceMsgLog::TraceMessage(int level, CString str) { CString traceMsg(_T("")); switch(level) { case MSGINFO: traceMsg.Append(_T("[INFO] ")); break; case MSGERROR: traceMsg.Append(_T("[ERR] ")); break; case JAVASCRIPT_ALERT: traceMsg.Append(_T("[JAVASCRIPT ALERT] ")); break; default: traceMsg.Append(_T("[DEBUG] ")); break; } // traceMsg.Append(str); // TraceMessage(traceMsg); }
int32_t TR_AsyncCheckInsertion::insertReturnAsyncChecks(TR::Optimization *opt, const char *counterPrefix) { TR::Compilation * const comp = opt->comp(); if (opt->trace()) traceMsg(comp, "Inserting return asyncchecks (%s)\n", counterPrefix); int numAsyncChecksInserted = 0; for (TR::TreeTop *treeTop = comp->getStartTree(); treeTop; /* nothing */ ) { TR::Block *block = treeTop->getNode()->getBlock(); if (block->getLastRealTreeTop()->getNode()->getOpCode().isReturn() && performTransformation(comp, "%sInserting return asynccheck (%s) in block_%d\n", opt->optDetailString(), counterPrefix, block->getNumber())) { insertAsyncCheck(block, comp, counterPrefix); numAsyncChecksInserted++; } treeTop = block->getExit()->getNextRealTreeTop(); } return numAsyncChecksInserted; }
void OMR::CodeGenPhase::performEmitSnippetsPhase(TR::CodeGenerator * cg, TR::CodeGenPhase * phase) { TR::Compilation * comp = cg->comp(); phase->reportPhase(EmitSnippetsPhase); TR::LexicalMemProfiler mp("Emit Snippets", comp->phaseMemProfiler()); LexicalTimer pt("Emit Snippets", comp->phaseTimer()); cg->emitSnippets(); if (comp->getOption(TR_EnableOSR)) { comp->getOSRCompilationData()->checkOSRLimits(); comp->getOSRCompilationData()->compressInstruction2SharedSlotMap(); } if (comp->getOption(TR_TraceCG) || comp->getOptions()->getTraceCGOption(TR_TraceCGPostBinaryEncoding)) { diagnostic("\nbuffer start = %8x, code start = %8x, buffer length = %d", cg->getBinaryBufferStart(), cg->getCodeStart(), cg->getEstimatedCodeLength()); diagnostic("\n"); const char * title = "Post Binary Instructions"; comp->getDebug()->dumpMethodInstrs(comp->getOutFile(), title, false, true); traceMsg(comp,"<snippets>"); comp->getDebug()->print(comp->getOutFile(), cg->getSnippetList()); traceMsg(comp,"\n</snippets>\n"); auto iterator = cg->getSnippetList().begin(); int32_t estimatedSnippetStart = cg->getEstimatedSnippetStart(); while (iterator != cg->getSnippetList().end()) { estimatedSnippetStart += (*iterator)->getLength(estimatedSnippetStart); ++iterator; } int32_t snippetLength = estimatedSnippetStart - cg->getEstimatedSnippetStart(); diagnostic("\nAmount of code memory allocated for this function = %d" "\nAmount of code memory consumed for this function = %d" "\nAmount of snippet code memory consumed for this function = %d\n\n", cg->getEstimatedCodeLength(), cg->getCodeLength(), snippetLength); } }
int32_t TR::IA32SystemLinkage::layoutParm(TR::ParameterSymbol *parmSymbol, int32_t &dataCursor, uint16_t &intReg, uint16_t &floatReg, TR::parmLayoutResult &layoutResult) { layoutResult.abstract |= TR::parmLayoutResult::ON_STACK; int32_t align = layoutTypeOnStack(parmSymbol->getDataType(), dataCursor, layoutResult); if (comp()->getOption(TR_TraceCG)) traceMsg(comp(), "layout param symbol %p on stack\n", parmSymbol); return align; }
void setMaxNestingDepth(int16_t f) { if (f > SHRT_MAX-1) { TR_ASSERT(0, "max nesting depth must be less than or equal to SHRT_MAX-1"); traceMsg(comp(), "max nesting depth must be less than or equal to SHRT_MAX-1"); throw TR::CompilationException(); } _maxNestingDepth = f; }
void TR_ReachabilityAnalysis::traverse(blocknum_t blockNum, int32_t depth, blocknum_t *stack, blocknum_t *depthMap, TR_BitVector *result) { // // This is DeRemer and Penello's "digraph" algorithm // bool trace = comp()->getOption(TR_TraceReachability); // Initialize state for this block // stack[depth++] = blockNum; depthMap[blockNum] = depth; bool value = isOrigin(getBlock(blockNum)); if (trace) traceMsg(comp(), " traverse %sblock_%d depth %d\n", value? "origin ":"", blockNum, depth); result->setTo(blockNum, value); // Recursively propagate from inputs // propagateInputs(blockNum, depth, stack, depthMap, result); // Propagate result around the strongly connected component that includes blockNum // if (depthMap[blockNum] == depth) { while(1) { blocknum_t top = stack[--depth]; depthMap[top] = INT_MAX; if (top == blockNum) { break; } else { if (trace) traceMsg(comp(), " Loop: propagate block_%d to block_%d\n", blockNum, top); result->setTo(top, result->isSet(blockNum)); } } } }
void TR_ReachabilityAnalysis::propagateOneInput(blocknum_t inputBlockNum, blocknum_t blockNum, int32_t depth, blocknum_t *stack, blocknum_t *depthMap, TR_BitVector *result) { if (inputBlockNum == blockNum) return; if (depthMap[inputBlockNum] == 0) traverse(inputBlockNum, depth, stack, depthMap, result); depthMap[blockNum] = std::min(depthMap[blockNum], depthMap[inputBlockNum]); if (result->isSet(inputBlockNum)) { if (comp()->getOption(TR_TraceReachability)) traceMsg(comp(), " Propagate block_%d to block_%d\n", blockNum, inputBlockNum); result->set(blockNum); } else { if (comp()->getOption(TR_TraceReachability)) traceMsg(comp(), " No change to block_%d from block_%d\n", blockNum, inputBlockNum); } }
LexicalXmlTag::LexicalXmlTag(TR::CodeGenerator * cg): cg(cg) { TR::Compilation *comp = cg->comp(); if (comp->getOption(TR_TraceOptDetails) || comp->getOption(TR_TraceCG)) { const char *hotnessString = comp->getHotnessName(comp->getMethodHotness()); traceMsg(comp, "<codegen\n" "\tmethod=\"%s\"\n" "\thotness=\"%s\">\n", comp->signature(), hotnessString); } }
void CTraceMsgLog::TraceWithMemory(CString str) { CString traceMsg(L"[IN3_TRACE]"); // // @ note // memory °ü·Ã string ¸¸µéÀð. // traceMsg.Append(str); traceMsg.Append(str); traceMsg.Append(L"\r\n"); TRACE(traceMsg); }