TinyPtrVector<Action *> RealizeRMC::collectEdges(StringRef name) { TinyPtrVector<Action *> matches; if (name == "pre" || name == "post") return matches; // Since multiple blocks can have the same tag, we search for // them by name. // We could make this more efficient by building maps but I don't think // it is going to matter. for (auto & a : actions_) { if (a.name == name) { matches.push_back(&a); } } if (matches.size() == 0) { errs() << "Error: use of nonexistent label '" << name << "' in function '" << func_.getName() << "'\n"; rmc_error(); } return matches; }
/// propagateSiblingValue - Propagate the value in SVI to dependents if it is /// known. Otherwise remember the dependency for later. /// /// @param SVIIter SibValues entry to propagate. /// @param VNI Dependent value, or NULL to propagate to all saved dependents. void InlineSpiller::propagateSiblingValue(SibValueMap::iterator SVIIter, VNInfo *VNI) { SibValueMap::value_type *SVI = &*SVIIter; // When VNI is non-NULL, add it to SVI's deps, and only propagate to that. TinyPtrVector<VNInfo*> FirstDeps; if (VNI) { FirstDeps.push_back(VNI); SVI->second.Deps.push_back(VNI); } // Has the value been completely determined yet? If not, defer propagation. if (!SVI->second.hasDef()) return; // Work list of values to propagate. SmallSetVector<SibValueMap::value_type *, 8> WorkList; WorkList.insert(SVI); do { SVI = WorkList.pop_back_val(); TinyPtrVector<VNInfo*> *Deps = VNI ? &FirstDeps : &SVI->second.Deps; VNI = 0; SibValueInfo &SV = SVI->second; if (!SV.SpillMBB) SV.SpillMBB = LIS.getMBBFromIndex(SV.SpillVNI->def); DEBUG(dbgs() << " prop to " << Deps->size() << ": " << SVI->first->id << '@' << SVI->first->def << ":\t" << SV); assert(SV.hasDef() && "Propagating undefined value"); // Should this value be propagated as a preferred spill candidate? We don't // propagate values of registers that are about to spill. bool PropSpill = !DisableHoisting && !isRegToSpill(SV.SpillReg); unsigned SpillDepth = ~0u; for (TinyPtrVector<VNInfo*>::iterator DepI = Deps->begin(), DepE = Deps->end(); DepI != DepE; ++DepI) { SibValueMap::iterator DepSVI = SibValues.find(*DepI); assert(DepSVI != SibValues.end() && "Dependent value not in SibValues"); SibValueInfo &DepSV = DepSVI->second; if (!DepSV.SpillMBB) DepSV.SpillMBB = LIS.getMBBFromIndex(DepSV.SpillVNI->def); bool Changed = false; // Propagate defining instruction. if (!DepSV.hasDef()) { Changed = true; DepSV.DefMI = SV.DefMI; DepSV.DefByOrigPHI = SV.DefByOrigPHI; } // Propagate AllDefsAreReloads. For PHI values, this computes an AND of // all predecessors. if (!SV.AllDefsAreReloads && DepSV.AllDefsAreReloads) { Changed = true; DepSV.AllDefsAreReloads = false; } // Propagate best spill value. if (PropSpill && SV.SpillVNI != DepSV.SpillVNI) { if (SV.SpillMBB == DepSV.SpillMBB) { // DepSV is in the same block. Hoist when dominated. if (DepSV.KillsSource && SV.SpillVNI->def < DepSV.SpillVNI->def) { // This is an alternative def earlier in the same MBB. // Hoist the spill as far as possible in SpillMBB. This can ease // register pressure: // // x = def // y = use x // s = copy x // // Hoisting the spill of s to immediately after the def removes the // interference between x and y: // // x = def // spill x // y = use x<kill> // // This hoist only helps when the DepSV copy kills its source. Changed = true; DepSV.SpillReg = SV.SpillReg; DepSV.SpillVNI = SV.SpillVNI; DepSV.SpillMBB = SV.SpillMBB; } } else { // DepSV is in a different block. if (SpillDepth == ~0u) SpillDepth = Loops.getLoopDepth(SV.SpillMBB); // Also hoist spills to blocks with smaller loop depth, but make sure // that the new value dominates. Non-phi dependents are always // dominated, phis need checking. if ((Loops.getLoopDepth(DepSV.SpillMBB) > SpillDepth) && (!DepSVI->first->isPHIDef() || MDT.dominates(SV.SpillMBB, DepSV.SpillMBB))) { Changed = true; DepSV.SpillReg = SV.SpillReg; DepSV.SpillVNI = SV.SpillVNI; DepSV.SpillMBB = SV.SpillMBB; } } } if (!Changed) continue; // Something changed in DepSVI. Propagate to dependents. WorkList.insert(&*DepSVI); DEBUG(dbgs() << " update " << DepSVI->first->id << '@' << DepSVI->first->def << " to:\t" << DepSV); } } while (!WorkList.empty()); }