bool MDNodeMapper::createPOT(UniquedGraph &G, const MDNode &FirstN) { assert(G.Info.empty() && "Expected a fresh traversal"); assert(FirstN.isUniqued() && "Expected uniqued node in POT"); // Construct a post-order traversal of the uniqued subgraph under FirstN. bool AnyChanges = false; SmallVector<POTWorklistEntry, 16> Worklist; Worklist.push_back(POTWorklistEntry(const_cast<MDNode &>(FirstN))); (void)G.Info[&FirstN]; while (!Worklist.empty()) { // Start or continue the traversal through the this node's operands. auto &WE = Worklist.back(); if (MDNode *N = visitOperands(G, WE.Op, WE.N->op_end(), WE.HasChanged)) { // Push a new node to traverse first. Worklist.push_back(POTWorklistEntry(*N)); continue; } // Push the node onto the POT. assert(WE.N->isUniqued() && "Expected only uniqued nodes"); assert(WE.Op == WE.N->op_end() && "Expected to visit all operands"); auto &D = G.Info[WE.N]; AnyChanges |= D.HasChanged = WE.HasChanged; D.ID = G.POT.size(); G.POT.push_back(WE.N); // Pop the node off the worklist. Worklist.pop_back(); } return AnyChanges; }
/// Remap the operands of an MDNode. /// /// If \c Node is temporary, uniquing cycles are ignored. If \c Node is /// distinct, uniquing cycles are resolved as they're found. /// /// \pre \c Node.isDistinct() or \c Node.isTemporary(). static bool remapOperands(MDNode &Node, SmallVectorImpl<MDNode *> &DistinctWorklist, ValueToValueMapTy &VM, RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer) { assert(!Node.isUniqued() && "Expected temporary or distinct node"); const bool IsDistinct = Node.isDistinct(); bool AnyChanged = false; for (unsigned I = 0, E = Node.getNumOperands(); I != E; ++I) { Metadata *Old = Node.getOperand(I); Metadata *New = mapMetadataOp(Old, DistinctWorklist, VM, Flags, TypeMapper, Materializer); if (Old != New) { AnyChanged = true; Node.replaceOperandWith(I, New); // Resolve uniquing cycles underneath distinct nodes on the fly so they // don't infect later operands. if (IsDistinct) resolveCycles(New); } } return AnyChanged; }
void MDNodeMapper::remapOperands(MDNode &N, OperandMapper mapOperand) { assert(!N.isUniqued() && "Expected distinct or temporary nodes"); for (unsigned I = 0, E = N.getNumOperands(); I != E; ++I) { Metadata *Old = N.getOperand(I); Metadata *New = mapOperand(Old); if (Old != New) N.replaceOperandWith(I, New); } }
/// Remap the operands of an MDNode. static bool remapOperands(MDNode &Node, SmallVectorImpl<MDNode *> &DistinctWorklist, ValueToValueMapTy &VM, RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer) { assert(!Node.isUniqued() && "Expected temporary or distinct node"); bool AnyChanged = false; for (unsigned I = 0, E = Node.getNumOperands(); I != E; ++I) { Metadata *Old = Node.getOperand(I); Metadata *New = mapMetadataOp(Old, DistinctWorklist, VM, Flags, TypeMapper, Materializer); if (Old != New) { AnyChanged = true; Node.replaceOperandWith(I, New); } } return AnyChanged; }