void TR::ValidateLivenessBoundaries::validate(TR::ResolvedMethodSymbol *methodSymbol) { /** * These must be initialized at the start of every validate call, * since the same Rule object can be used multiple times to validate * the IL at different stages of the compilation. */ TR::NodeSideTable<TR::NodeState> nodeStates(comp()->trMemory()); /** * Similar to NodeChecklist, but more compact. Rather than track * node global indexes, which can be sparse, this tracks local * indexes, which are relatively dense. Furthermore, the _basis field * allows us not to waste space on nodes we saw in prior blocks. * As the name suggests, used to keep track of live Nodes. */ TR::LiveNodeWindow liveNodes(nodeStates, comp()->trMemory()); TR::TreeTop *start = methodSymbol->getFirstTreeTop(); TR::TreeTop *stop = methodSymbol->getLastTreeTop(); for (TR::PostorderNodeOccurrenceIterator iter(start, comp(), "VALIDATE_LIVENESS_BOUNDARIES"); iter != stop; ++iter) { TR::Node *node = iter.currentNode(); updateNodeState(node, nodeStates, liveNodes); if (node->getOpCodeValue() == TR::BBEnd) { /* Determine whether this is the end of an extended block */ bool isEndOfExtendedBlock = false; TR::TreeTop *nextTree = iter.currentTree()->getNextTreeTop(); if (nextTree) { TR::checkILCondition(node, nextTree->getNode()->getOpCodeValue() == TR::BBStart, comp(), "Expected BBStart after BBEnd"); isEndOfExtendedBlock = ! nextTree->getNode()->getBlock()->isExtensionOfPreviousBlock(); } else { isEndOfExtendedBlock = true; } if (isEndOfExtendedBlock) { /* Ensure there are no nodes live across the end of a block */ validateEndOfExtendedBlockBoundary(node, liveNodes); } } } }
bool TR::ILValidator::treesAreValid(TR::TreeTop *start, TR::TreeTop *stop) { checkSoundness(start, stop); for (PostorderNodeOccurrenceIterator iter(start, _comp, "VALIDATOR"); iter != stop; ++iter) { updateNodeState(iter); // General node validation // validateNode(iter); // // Additional specific kinds of validation // TR::Node *node = iter.currentNode(); if (node->getOpCodeValue() == TR::BBEnd) { // Determine whether this is the end of an extended block // bool isEndOfExtendedBlock = false; TR::TreeTop *nextTree = iter.currentTree()->getNextTreeTop(); if (nextTree) { validityRule(iter, nextTree->getNode()->getOpCodeValue() == TR::BBStart, "Expected BBStart after BBEnd"); isEndOfExtendedBlock = ! nextTree->getNode()->getBlock()->isExtensionOfPreviousBlock(); } else { isEndOfExtendedBlock = true; } if (isEndOfExtendedBlock) validateEndOfExtendedBlock(iter); } auto opcode = node->getOpCode(); if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount) { // Validate child expectations // const auto expChildCount = opcode.expectedChildCount(); const auto actChildCount = node->getNumChildren(); // validate child count if (!opcode.canHaveGlRegDeps()) { // in the common case, no GlRegDeps child is expect nor present validityRule(iter, actChildCount == expChildCount, "Child count %d does not match expected value of %d", actChildCount, expChildCount); } else if (actChildCount == (expChildCount + 1)) { // adjust expected child number to account for a possible extra GlRegDeps // child and make sure the last child is actually a GlRegDeps validityRule(iter, node->getChild(actChildCount - 1)->getOpCodeValue() == TR::GlRegDeps, "Child count %d does not match expected value of %d (%d without GlRegDeps) and last child is not a GlRegDeps", actChildCount, expChildCount + 1, expChildCount); } else { // if expected and actual child counts don't match, then the child // count is just wrong, even with an expected GlRegDeps validityRule(iter, actChildCount == expChildCount, "Child count %d matches neither expected values of %d (without GlRegDeps) nor %d (with GlRegDeps)", actChildCount, expChildCount, expChildCount + 1); } // validate child types for (auto i = 0; i < actChildCount; ++i) { auto childOpcode = node->getChild(i)->getOpCode(); if (childOpcode.getOpCodeValue() != TR::GlRegDeps) { const auto expChildType = opcode.expectedChildType(i); const auto actChildType = childOpcode.getDataType().getDataType(); const auto expChildTypeName = expChildType == ILChildProp::UnspecifiedChildType ? "UnspecifiedChildType" : TR::DataType::getName(expChildType); const auto actChildTypeName = TR::DataType::getName(actChildType); validityRule(iter, expChildType == ILChildProp::UnspecifiedChildType || actChildType == expChildType, "Child %d has unexpected type %s (expected %s)" , i, actChildTypeName, expChildTypeName); } else { // make sure the node is allowed to have a GlRegDeps child // and make sure that it is the last child validityRule(iter, opcode.canHaveGlRegDeps() && (i == actChildCount - 1), "Unexpected GlRegDeps child %d", i); } } } } return _isValidSoFar; }