static void markEscapingInst(Inst* inst,BitSet& escapingInsts) { if (escapingInsts.setBit(inst->getId(),true)) // already known to escape return; switch (inst->getOpcode()) { case Op_Copy: case Op_TauStaticCast: case Op_TauCast: case Op_TauAsType: case Op_TauCheckNull: case Op_StVar: case Op_UncompressRef: case Op_CompressRef: // mark source as escaping markEscapingInst(inst->getSrc(0)->getInst(),escapingInsts); break; // // in the absence of ssa form, loads of vars can conservatively escape // if we had SSA form, LdVar would follow its use-def chain to the // StVar or phi instruction that defines its SSA variable. // case Op_LdVar: break; case Op_Catch: case Op_DefArg: case Op_LdRef: case Op_LdConstant: case Op_NewObj: case Op_NewArray: // no src operands to mark break; case Op_NewMultiArray: break; // // sources of loads do not escape further // case Op_TauLdInd: case Op_TauLdField: case Op_LdStatic: case Op_TauLdElem: break; // // calls should already be marked as escaping // case Op_DirectCall: case Op_TauVirtualCall: case Op_IndirectCall: case Op_IndirectMemoryCall: break; // // managed pointers that escape // case Op_LdArrayBaseAddr: case Op_AddScaledIndex: case Op_LdFieldAddr: case Op_LdElemAddr: case Op_AddOffset: // base pointer escapes markEscapingInst(inst->getSrc(0)->getInst(),escapingInsts); break; case Op_LdStaticAddr: case Op_LdVarAddr: break; default: ::std::cerr << "ERROR: unknown escaping ref opcode: " << inst->getOperation().getOpcodeString() << ::std::endl; assert(0); break; } }
static void calculateReachableNodesInLoop(LoopNode* loop, Node* node, Node* stopNode, BitSet& flags) { int id = node->getId(); if (!loop->inLoop(node) || node == stopNode || flags.getBit(id)) { return; } flags.setBit(id, true); const Edges& edges = node->getOutEdges(); for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) { Edge* e = *ite; Node* nextNode = e->getTargetNode(); if (nextNode != loop->getHeader()) { calculateReachableNodesInLoop(loop, nextNode, stopNode, flags); } } }