コード例 #1
0
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;
}
コード例 #2
0
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;
}