[llvm-commits] [llvm] r171524 - in /llvm/trunk: lib/Target/X86/CMakeLists.txt lib/Target/X86/X86.h lib/Target/X86/X86.td lib/Target/X86/X86PadShortFunction.cpp lib/Target/X86/X86Subtarget.cpp lib/Target/X86/X86Subtarget.h lib/Target/X86/X86TargetMachine.cpp test/CodeGen/X86/atom-pad-short-functions.ll test/CodeGen/X86/fast-isel-x86-64.ll test/CodeGen/X86/ret-mmx.ll test/CodeGen/X86/select.ll

Nadav Rotem nrotem at apple.com
Fri Jan 4 13:13:30 PST 2013


Preston,  I am not sure that adding a new pass is the right way to go.  Have you considered writing a simple peephole ?

Nadav


> eFunctionPass(ID)
> +                   , Threshold(4)
> +    {}

Braces should be on the same line.

> +
> +    virtual bool runOnMachineFunction(MachineFunction &MF);
> +
> +    virtual const char *getPassName() const
> +    {
> +      return "X86 Atom pad short functions";
> +    }
> +

braces.

> +  private:
> +    bool addPadding(MachineFunction &MF,
> +                    MachineBasicBlock &MBB,
> +                    MachineBasicBlock::iterator &MBBI,
> +                    unsigned int NOOPsToAdd);
> +
> +    void findReturn(MachineFunction &MF,
> +                    MachineBasicBlock &MBB,
> +                    unsigned int Cycles);
> +
> +    bool cyclesUntilReturn(MachineFunction &MF,
> +                        MachineBasicBlock &MBB,
> +                        unsigned int &Cycles,
> +                        MachineBasicBlock::iterator *Location = 0);
> +
> +    const unsigned int Threshold;
> +    std::map<int, unsigned int> ReturnBBs;
> +  };
> +
> +  char PadShortFunc::ID = 0;
> +}
> +
> +FunctionPass *llvm::createX86PadShortFunctions() {
> +  return new PadShortFunc();
> +}
> +
> +/// runOnMachineFunction - Loop over all of the basic blocks, inserting
> +/// NOOP instructions before early exits.
> +bool PadShortFunc::runOnMachineFunction(MachineFunction &MF) {
> +  // Process all basic blocks.
> +  ReturnBBs.clear();
> +
> +  // Search through basic blocks and mark the ones that have early returns
> +  findReturn(MF, *MF.begin(), 0);
> +
> +  int BBNum;
> +  MachineBasicBlock::iterator ReturnLoc;
> +  MachineBasicBlock *MBB;
> +
> +  unsigned int Cycles = 0;
> +  unsigned int BBCycles;
> +
> +  // Pad the identified basic blocks with NOOPs
> +  for (std::map<int, unsigned int>::iterator I = ReturnBBs.begin();
> +       I != ReturnBBs.end(); ++I) {
> +    BBNum = I->first;
> +    Cycles = I->second;
> +
> +    if (Cycles < Threshold) {
> +      MBB = MF.getBlockNumbered(BBNum);
> +      if (!cyclesUntilReturn(MF, *MBB, BBCycles, &ReturnLoc))
> +        continue;
> +
> +      addPadding(MF, *MBB, ReturnLoc, Threshold - Cycles);
> +      NumBBsPadded++;
> +    }
> +  }
> +
> +  return false;
> +}
> +
> +/// findReturn - Starting at MBB, follow control flow and add all
> +/// basic blocks that contain a return to ReturnBBs.
> +void PadShortFunc::findReturn(MachineFunction &MF,
> +                              MachineBasicBlock &MBB,
> +                              unsigned int Cycles)
> +{
> +  // If this BB has a r

braces. 

> eturn, note how many cycles it takes to get there.
> +  bool hasReturn = cyclesUntilReturn(MF, MBB, Cycles);
> +  if (Cycles >= Threshold)
> +    return;
> +
> +  if (hasReturn) {
> +    int BBNum = MBB.getNumber();
> +    ReturnBBs[BBNum] = std::max(ReturnBBs[BBNum], Cycles);
> +
> +    return;
> +  }
> +
> +  // Follow branches in BB and look for returns
> +  for (MachineBasicBlock::succ_iterator I = MBB.succ_begin();
> +       I != MBB.succ_end(); ++I) {
> +    findReturn(MF, **I, Cycles);
> +  }
> +}
> +
> +/// cyclesUntilReturn - if the MBB has a return instruction, set Location to
> +/// to the instruction and return true. Return false otherwise.
> +/// Cycles will be incremented by the number of cycles taken to reach the
> +/// return or the end of the BB, whichever occurs first.
> +bool PadShortFunc::cyclesUntilReturn(MachineFunction &MF,
> +                                  MachineBasicBlock &MBB,
> +                                  unsigned int &Cycles,
> +                                  MachineBasicBlock::iterator *Location)
> +{
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();

braces.

> +  const TargetMachine &Target = MF.getTarget();
> +
> +  for (MachineBasicBlock::iterator MBBI = MBB.begin(); MBBI != MBB.end();
> +       ++MBBI) {
> +    MachineInstr *MI = MBBI;
> +    // Mark basic blocks with a return instruction. Calls to other functions
> +    // do not count because the called function will be padded, if necessary
> +    if (MI->isReturn() && !MI->isCall()) {
> +      if (Location)
> +        *Location = MBBI;
> +      return true;
> +    }
> +
> +    Cycles += TII.getInstrLatency(Target.getInstrItineraryData(), MI);
> +  }
> +
> +  return false;
> +}
> +
> +/// addPadding - Add the given number of NOOP instructions to the function
> +/// right before the return at MBBI
> +bool PadShortFunc::addPadding(MachineFunction &MF,
> +                              MachineBasicBlock &MBB,
> +                              MachineBasicBlock::iterator &MBBI,
> +                              unsigned int NOOPsToAdd)
> +{
> +  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
> +

Also here.

> +  DebugLoc DL = MBBI->getDebugLoc();
> +
> +  while (NOOPsToAdd-- > 0) {
> +    // Since Atom has two instruction execution ports,
> +    // the code emits two noops, which will be executed in parallell
> +    // during one cycle.
> +    BuildMI(MBB, MBBI, DL, TII.get(X86::NOOP));
> +    BuildMI(MBB, MBBI, DL, TII.get(X86::NOOP));
> +  }
> +
> +  return true;
> +}



More information about the llvm-commits mailing list