void BlockState::processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem, SILValue Val, RLEKind Kind) { // Initialize the LSLocation. LSLocation L(Mem); // If we cant figure out the Base or Projection Path for the read, simply // ignore it for now. if (!L.isValid()) return; // Expand the given LSLocation and Val into individual fields and process // them as separate reads. LSLocationList Locs; LSLocation::expand(L, &I->getModule(), Locs, Ctx.getTE()); // Are we computing available set ?. if (isComputeAvailSet(Kind)) { for (auto &X : Locs) { if (isTrackingLSLocation(Ctx.getLSLocationBit(X))) continue; updateForwardSetForRead(Ctx, Ctx.getLSLocationBit(X)); } return; } // Are we computing available values ?. bool CanForward = true; if (isComputeAvailValue(Kind) || isPerformRLE(Kind)) { LSValueList Vals; LSValue::expand(Val, &I->getModule(), Vals, Ctx.getTE()); for (unsigned i = 0; i < Locs.size(); ++i) { if (isTrackingLSLocation(Ctx.getLSLocationBit(Locs[i]))) continue; updateForwardValForRead(Ctx, Ctx.getLSLocationBit(Locs[i]), Ctx.getLSValueBit(Vals[i])); CanForward = false; } } // Simply return if we are not performing RLE or we do not have all the // values available to perform RLE. if (!isPerformRLE(Kind) || !CanForward) return; // Lastly, forward value to the load. setupRLE(Ctx, I, Mem); }
void BlockState::processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem, SILValue Val, RLEKind Kind) { // Initialize the LSLocation. LSLocation L(Mem); // If we cant figure out the Base or Projection Path for the write, // process it as an unknown memory instruction. if (!L.isValid()) { processUnknownWriteInst(Ctx, I, Kind); return; } // Expand the given location and val into individual fields and process // them as separate writes. LSLocationList Locs; LSLocation::expand(L, &I->getModule(), Locs, Ctx.getTE()); // Are we computing available set ? if (isComputeAvailSet(Kind)) { for (unsigned i = 0; i < Locs.size(); ++i) { updateForwardSetForWrite(Ctx, Ctx.getLSLocationBit(Locs[i])); } return; } // Are we computing available value ? if (isComputeAvailValue(Kind) || isPerformRLE(Kind)) { LSValueList Vals; LSValue::expand(Val, &I->getModule(), Vals, Ctx.getTE()); for (unsigned i = 0; i < Locs.size(); ++i) { updateForwardValForWrite(Ctx, Ctx.getLSLocationBit(Locs[i]), Ctx.getLSValueBit(Vals[i])); } return; } llvm_unreachable("Unknown RLE compute kind"); }
SILValue BlockState::reduceValuesAtEndOfBlock(RLEContext &Ctx, LSLocation &L) { // First, collect current available locations and their corresponding values // into a map. LSLocationValueMap Values; LSLocationList Locs; LSLocation::expand(L, &BB->getModule(), Locs, Ctx.getTE()); // Find the values that this basic block defines and the locations which // we do not have a concrete value in the current basic block. ValueTableMap &OTM = getForwardValOut(); for (unsigned i = 0; i < Locs.size(); ++i) { Values[Locs[i]] = Ctx.getLSValue(OTM[Ctx.getLSLocationBit(Locs[i])]); } // Second, reduce the available values into a single SILValue we can use to // forward. SILValue TheForwardingValue; TheForwardingValue = LSValue::reduce(L, &BB->getModule(), Values, BB->getTerminator(), Ctx.getTE()); /// Return the forwarding value. return TheForwardingValue; }
BlockState::ValueState BlockState::getValueStateAtEndOfBlock(RLEContext &Ctx, LSLocation &L) { LSLocationList Locs; LSLocation::expand(L, &BB->getModule(), Locs, Ctx.getTE()); // Find number of covering value and concrete values for the locations // expanded from the given location. unsigned CSCount = 0, CTCount = 0; ValueTableMap &OTM = getForwardValOut(); for (auto &X : Locs) { LSValue &V = Ctx.getLSValue(OTM[Ctx.getLSLocationBit(X)]); if (V.isCoveringValue()) { ++CSCount; continue; } ++CTCount; } if (CSCount == Locs.size()) return ValueState::CoverValues; if (CTCount == Locs.size()) return ValueState::ConcreteValues; return ValueState::CoverAndConcreteValues; }