/// InstantiateNonterminals - If this pattern refers to any nonterminals which /// are not themselves completely resolved, clone the nonterminal and resolve it /// with the using context we provide. /// void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) { if (!isLeaf()) { for (unsigned i = 0, e = getNumChildren(); i != e; ++i) getChild(i)->InstantiateNonterminals(ISE); return; } // If this is a leaf, it might be a reference to a nonterminal! Check now. Record *R = getValueRecord(); if (R->isSubClassOf("Nonterminal")) { Pattern *NT = ISE.getPattern(R); if (!NT->isResolved()) { // We found an unresolved nonterminal reference. Ask the ISE to clone // it for us, then update our reference to the fresh, new, resolved, // nonterminal. Value = new DefInit(ISE.InstantiateNonterminal(NT, getType())); } } }
/// InstantiateNonterminal - This method takes the nonterminal specified by /// NT, which should not be completely resolved, clones it, applies ResultTy /// to its root, then runs the type inference stuff on it. This should /// produce a newly resolved nonterminal, which we make a record for and /// return. To be extra fancy and efficient, this only makes one clone for /// each type it is instantiated with. Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT, MVT::ValueType ResultTy) { assert(!NT->isResolved() && "Nonterminal is already resolved!"); // Check to see if we have already instantiated this pair... Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)]; if (Slot) return Slot; Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy)); // Copy over the superclasses... const std::vector<Record*> &SCs = NT->getRecord()->getSuperClasses(); for (unsigned i = 0, e = SCs.size(); i != e; ++i) New->addSuperClass(SCs[i]); DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName() << "' for type '" << getName(ResultTy) << "', producing '" << New->getName() << "'\n"); // Copy the pattern... Pattern *NewPat = NT->clone(New); // Apply the type to the root... NewPat->getTree()->updateNodeType(ResultTy, New->getName()); // Infer types... NewPat->InferAllTypes(); // Make sure everything is good to go now... if (!NewPat->isResolved()) NewPat->error("Instantiating nonterminal did not resolve all types!"); // Add the pattern to the patterns map, add the record to the RecordKeeper, // return the new record. Patterns[New] = NewPat; Records.addDef(New); return Slot = New; }