void BlockState::mergePredecessorState(RLEContext &Ctx, BlockState &OtherState, RLEKind Kind) { // Are we computing the available set ? if (isComputeAvailSet(Kind)) { ForwardSetIn &= OtherState.ForwardSetOut; return; } // Are we computing the available value ? if (isComputeAvailValue(Kind) || isPerformRLE(Kind)) { // Merge in the predecessor state. llvm::SmallVector<unsigned, 8> LocDeleteList; for (unsigned i = 0; i < ForwardSetIn.size(); ++i) { if (OtherState.ForwardSetOut[i]) { // There are multiple values from multiple predecessors, set this as // a covering value. We do not need to track the value itself, as we // can always go to the predecessors BlockState to find it. ForwardValIn[i] = Ctx.getLSValueBit(LSValue(true)); continue; } // If this location does have an available value, then clear it. stopTrackingLSLocation(i); } } }
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"); }