SILValue BBState::computeForwardingValues(RLEContext &Ctx, MemLocation &L, SILInstruction *InsertPt, bool UseForwardValOut) { SILBasicBlock *ParentBB = InsertPt->getParent(); bool IsTerminator = (InsertPt == ParentBB->getTerminator()); // We do not have a SILValue for the current MemLocation, try to construct // one. // // Collect the locations and their corresponding values into a map. // First, collect current available locations and their corresponding values // into a map. MemLocationValueMap Values; if (!Ctx.gatherValues(ParentBB, L, Values, UseForwardValOut)) return SILValue(); // If the InsertPt is the terminator instruction of the basic block, we // *refresh* it as terminator instruction could be deleted as a result // of adding new edge values to the terminator instruction. if (IsTerminator) InsertPt = ParentBB->getTerminator(); // Second, reduce the available values into a single SILValue we can use to // forward. SILValue TheForwardingValue; TheForwardingValue = MemLocation::reduceWithValues(L, &ParentBB->getModule(), Values, InsertPt); /// Return the forwarding value. return TheForwardingValue; }
bool BBState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) { // Try to construct a SILValue for the current MemLocation. // // Collect the locations and their corresponding values into a map. MemLocation L(Mem); MemLocationValueMap Values; if (!Ctx.gatherValues(I->getParent(), L, Values, false)) return false; // Reduce the available values into a single SILValue we can use to forward. SILModule *Mod = &I->getModule(); SILValue TheForwardingValue; TheForwardingValue = MemLocation::reduceWithValues(L, Mod, Values, I); if (!TheForwardingValue) return false; // Now we have the forwarding value, record it for forwarding!. // // NOTE: we do not perform the RLE right here because doing so could introduce // new MemLocations. // // e.g. // %0 = load %x // %1 = load %x // %2 = extract_struct %1, #a // %3 = load %2 // // If we perform the RLE and replace %1 with %0, we end up having a memory // location we do not have before, i.e. Base == %0, and Path == #a. // // We may be able to add the MemLocation to the vault, but it gets // complicated very quickly, e.g. we need to resize the bit vectors size, // etc. // // However, since we already know the instruction to replace and the value to // replace it with, we can record it for now and forwarded it after all the // forwardable values are recorded in the function. // RedundantLoads[I] = TheForwardingValue; return true; }