Ejemplo n.º 1
0
/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
/// frame indexes with appropriate references.
///
bool PEI::runOnMachineFunction(MachineFunction &Fn) {
  const Function* F = Fn.getFunction();
  const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
  const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();

  assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");

  RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr;
  FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);

  // Calculate the MaxCallFrameSize and AdjustsStack variables for the
  // function's frame information. Also eliminates call frame pseudo
  // instructions.
  calculateCallsInformation(Fn);

  // Determine which of the registers in the callee save list should be saved.
  BitVector SavedRegs;
  TFI->determineCalleeSaves(Fn, SavedRegs, RS);

  // Insert spill code for any callee saved registers that are modified.
  assignCalleeSavedSpillSlots(Fn, SavedRegs);

  // Determine placement of CSR spill/restore code:
  // place all spills in the entry block, all restores in return blocks.
  calculateSets(Fn);

  // Add the code to save and restore the callee saved registers.
  if (!F->hasFnAttribute(Attribute::Naked))
    insertCSRSpillsAndRestores(Fn);

  // Allow the target machine to make final modifications to the function
  // before the frame layout is finalized.
  TFI->processFunctionBeforeFrameFinalized(Fn, RS);

  // Calculate actual frame offsets for all abstract stack objects...
  calculateFrameObjectOffsets(Fn);

  // Add prolog and epilog code to the function.  This function is required
  // to align the stack frame as necessary for any stack variables or
  // called functions.  Because of this, calculateCalleeSavedRegisters()
  // must be called before this function in order to set the AdjustsStack
  // and MaxCallFrameSize variables.
  if (!F->hasFnAttribute(Attribute::Naked))
    insertPrologEpilogCode(Fn);

  // Replace all MO_FrameIndex operands with physical register references
  // and actual offsets.
  //
  replaceFrameIndices(Fn);

  // If register scavenging is needed, as we've enabled doing it as a
  // post-pass, scavenge the virtual registers that frame index elimination
  // inserted.
  if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging)
    scavengeFrameVirtualRegs(Fn);

  // Clear any vregs created by virtual scavenging.
  Fn.getRegInfo().clearVirtRegs();

  // Warn on stack size when we exceeds the given limit.
  MachineFrameInfo *MFI = Fn.getFrameInfo();
  uint64_t StackSize = MFI->getStackSize();
  if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) {
    DiagnosticInfoStackSize DiagStackSize(*F, StackSize);
    F->getContext().diagnose(DiagStackSize);
  }

  delete RS;
  SaveBlocks.clear();
  RestoreBlocks.clear();
  MFI->setSavePoint(nullptr);
  MFI->setRestorePoint(nullptr);
  return true;
}
Ejemplo n.º 2
0
bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
  if (MF.empty())
    return false;
  DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');

  init(MF);

  for (MachineBasicBlock &MBB : MF) {
    DEBUG(dbgs() << "Look into: " << MBB.getNumber() << ' ' << MBB.getName()
                 << '\n');

    for (const MachineInstr &MI : MBB) {
      if (!useOrDefCSROrFI(MI))
        continue;
      // Save (resp. restore) point must dominate (resp. post dominate)
      // MI. Look for the proper basic block for those.
      updateSaveRestorePoints(MBB);
      // If we are at a point where we cannot improve the placement of
      // save/restore instructions, just give up.
      if (!ArePointsInteresting()) {
        DEBUG(dbgs() << "No Shrink wrap candidate found\n");
        return false;
      }
      // No need to look for other instructions, this basic block
      // will already be part of the handled region.
      break;
    }
  }
  if (!ArePointsInteresting()) {
    // If the points are not interesting at this point, then they must be null
    // because it means we did not encounter any frame/CSR related code.
    // Otherwise, we would have returned from the previous loop.
    assert(!Save && !Restore && "We miss a shrink-wrap opportunity?!");
    DEBUG(dbgs() << "Nothing to shrink-wrap\n");
    return false;
  }

  DEBUG(dbgs() << "\n ** Results **\nFrequency of the Entry: " << EntryFreq
               << '\n');

  do {
    DEBUG(dbgs() << "Shrink wrap candidates (#, Name, Freq):\nSave: "
                 << Save->getNumber() << ' ' << Save->getName() << ' '
                 << MBFI->getBlockFreq(Save).getFrequency() << "\nRestore: "
                 << Restore->getNumber() << ' ' << Restore->getName() << ' '
                 << MBFI->getBlockFreq(Restore).getFrequency() << '\n');

    bool IsSaveCheap;
    if ((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
        EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency())
      break;
    DEBUG(dbgs() << "New points are too expensive\n");
    MachineBasicBlock *NewBB;
    if (!IsSaveCheap) {
      Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
      if (!Save)
        break;
      NewBB = Save;
    } else {
      // Restore is expensive.
      Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
      if (!Restore)
        break;
      NewBB = Restore;
    }
    updateSaveRestorePoints(*NewBB);
  } while (Save && Restore);

  if (!ArePointsInteresting()) {
    ++NumCandidatesDropped;
    return false;
  }

  DEBUG(dbgs() << "Final shrink wrap candidates:\nSave: " << Save->getNumber()
               << ' ' << Save->getName() << "\nRestore: "
               << Restore->getNumber() << ' ' << Restore->getName() << '\n');

  MachineFrameInfo *MFI = MF.getFrameInfo();
  MFI->setSavePoint(Save);
  MFI->setRestorePoint(Restore);
  ++NumCandidates;
  return false;
}