LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
X86PadShortFunction.cpp
Go to the documentation of this file.
1 //===-------- X86PadShortFunction.cpp - pad short functions -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the pass which will pad short functions to prevent
11 // a stall if a function returns before the return address is ready. This
12 // is needed for some Intel Atom processors.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include <algorithm>
17 
18 #define DEBUG_TYPE "x86-pad-short-functions"
19 #include "X86.h"
20 #include "X86InstrInfo.h"
21 #include "llvm/ADT/Statistic.h"
25 #include "llvm/CodeGen/Passes.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/Support/Debug.h"
30 
31 using namespace llvm;
32 
33 STATISTIC(NumBBsPadded, "Number of basic blocks padded");
34 
35 namespace {
36  struct VisitedBBInfo {
37  // HasReturn - Whether the BB contains a return instruction
38  bool HasReturn;
39 
40  // Cycles - Number of cycles until return if HasReturn is true, otherwise
41  // number of cycles until end of the BB
42  unsigned int Cycles;
43 
44  VisitedBBInfo() : HasReturn(false), Cycles(0) {}
45  VisitedBBInfo(bool HasReturn, unsigned int Cycles)
46  : HasReturn(HasReturn), Cycles(Cycles) {}
47  };
48 
49  struct PadShortFunc : public MachineFunctionPass {
50  static char ID;
51  PadShortFunc() : MachineFunctionPass(ID)
52  , Threshold(4), TM(0), TII(0) {}
53 
54  virtual bool runOnMachineFunction(MachineFunction &MF);
55 
56  virtual const char *getPassName() const {
57  return "X86 Atom pad short functions";
58  }
59 
60  private:
61  void findReturns(MachineBasicBlock *MBB,
62  unsigned int Cycles = 0);
63 
64  bool cyclesUntilReturn(MachineBasicBlock *MBB,
65  unsigned int &Cycles);
66 
67  void addPadding(MachineBasicBlock *MBB,
69  unsigned int NOOPsToAdd);
70 
71  const unsigned int Threshold;
72 
73  // ReturnBBs - Maps basic blocks that return to the minimum number of
74  // cycles until the return, starting from the entry block.
76 
77  // VisitedBBs - Cache of previously visited BBs.
79 
80  const TargetMachine *TM;
81  const TargetInstrInfo *TII;
82  };
83 
84  char PadShortFunc::ID = 0;
85 }
86 
88  return new PadShortFunc();
89 }
90 
91 /// runOnMachineFunction - Loop over all of the basic blocks, inserting
92 /// NOOP instructions before early exits.
93 bool PadShortFunc::runOnMachineFunction(MachineFunction &MF) {
94  const AttributeSet &FnAttrs = MF.getFunction()->getAttributes();
95  if (FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
97  FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
99  return false;
100  }
101 
102  TM = &MF.getTarget();
103  TII = TM->getInstrInfo();
104 
105  // Search through basic blocks and mark the ones that have early returns
106  ReturnBBs.clear();
107  VisitedBBs.clear();
108  findReturns(MF.begin());
109 
110  bool MadeChange = false;
111 
112  MachineBasicBlock *MBB;
113  unsigned int Cycles = 0;
114 
115  // Pad the identified basic blocks with NOOPs
117  I != ReturnBBs.end(); ++I) {
118  MBB = I->first;
119  Cycles = I->second;
120 
121  if (Cycles < Threshold) {
122  // BB ends in a return. Skip over any DBG_VALUE instructions
123  // trailing the terminator.
124  assert(MBB->size() > 0 &&
125  "Basic block should contain at least a RET but is empty");
126  MachineBasicBlock::iterator ReturnLoc = --MBB->end();
127 
128  while (ReturnLoc->isDebugValue())
129  --ReturnLoc;
130  assert(ReturnLoc->isReturn() && !ReturnLoc->isCall() &&
131  "Basic block does not end with RET");
132 
133  addPadding(MBB, ReturnLoc, Threshold - Cycles);
134  NumBBsPadded++;
135  MadeChange = true;
136  }
137  }
138 
139  return MadeChange;
140 }
141 
142 /// findReturn - Starting at MBB, follow control flow and add all
143 /// basic blocks that contain a return to ReturnBBs.
144 void PadShortFunc::findReturns(MachineBasicBlock *MBB, unsigned int Cycles) {
145  // If this BB has a return, note how many cycles it takes to get there.
146  bool hasReturn = cyclesUntilReturn(MBB, Cycles);
147  if (Cycles >= Threshold)
148  return;
149 
150  if (hasReturn) {
151  ReturnBBs[MBB] = std::max(ReturnBBs[MBB], Cycles);
152  return;
153  }
154 
155  // Follow branches in BB and look for returns
157  I != MBB->succ_end(); ++I) {
158  if (*I == MBB)
159  continue;
160  findReturns(*I, Cycles);
161  }
162 }
163 
164 /// cyclesUntilReturn - return true if the MBB has a return instruction,
165 /// and return false otherwise.
166 /// Cycles will be incremented by the number of cycles taken to reach the
167 /// return or the end of the BB, whichever occurs first.
168 bool PadShortFunc::cyclesUntilReturn(MachineBasicBlock *MBB,
169  unsigned int &Cycles) {
170  // Return cached result if BB was previously visited
172  = VisitedBBs.find(MBB);
173  if (it != VisitedBBs.end()) {
174  VisitedBBInfo BBInfo = it->second;
175  Cycles += BBInfo.Cycles;
176  return BBInfo.HasReturn;
177  }
178 
179  unsigned int CyclesToEnd = 0;
180 
181  for (MachineBasicBlock::iterator MBBI = MBB->begin();
182  MBBI != MBB->end(); ++MBBI) {
183  MachineInstr *MI = MBBI;
184  // Mark basic blocks with a return instruction. Calls to other
185  // functions do not count because the called function will be padded,
186  // if necessary.
187  if (MI->isReturn() && !MI->isCall()) {
188  VisitedBBs[MBB] = VisitedBBInfo(true, CyclesToEnd);
189  Cycles += CyclesToEnd;
190  return true;
191  }
192 
193  CyclesToEnd += TII->getInstrLatency(TM->getInstrItineraryData(), MI);
194  }
195 
196  VisitedBBs[MBB] = VisitedBBInfo(false, CyclesToEnd);
197  Cycles += CyclesToEnd;
198  return false;
199 }
200 
201 /// addPadding - Add the given number of NOOP instructions to the function
202 /// just prior to the return at MBBI
203 void PadShortFunc::addPadding(MachineBasicBlock *MBB,
205  unsigned int NOOPsToAdd) {
206  DebugLoc DL = MBBI->getDebugLoc();
207 
208  while (NOOPsToAdd-- > 0) {
209  BuildMI(*MBB, MBBI, DL, TII->get(X86::NOOP));
210  BuildMI(*MBB, MBBI, DL, TII->get(X86::NOOP));
211  }
212 }
const Function * getFunction() const
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
Definition: Attributes.cpp:818
const HexagonInstrInfo * TII
FunctionPass * createX86PadShortFunctions()
std::vector< MachineBasicBlock * >::iterator succ_iterator
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
#define false
Definition: ConvertUTF.c:64
bundle_iterator< MachineInstr, instr_iterator > iterator
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:345
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
AttributeSet getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:170
#define I(x, y, z)
Definition: MD5.cpp:54
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:349
STATISTIC(NumBBsPadded,"Number of basic blocks padded")
const TargetMachine & getTarget() const
static int const Threshold
iterator find(const KeyT &Val)
Definition: DenseMap.h:108
Function must be optimized for size first.
Definition: Attributes.h:77