/llvm-3.1.src/lib/Target/Sparc/DelaySlotFiller.cpp

# · C++ · 323 lines · 236 code · 56 blank · 31 comment · 63 complexity · 24bd7833151f695a1f57de9e2c4aff2e MD5 · raw file

  1. //===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===//
  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 is a simple local pass that attempts to fill delay slots with useful
  11. // instructions. If no instructions can be moved into the delay slot, then a
  12. // NOP is placed.
  13. //===----------------------------------------------------------------------===//
  14. #define DEBUG_TYPE "delay-slot-filler"
  15. #include "Sparc.h"
  16. #include "llvm/CodeGen/MachineFunctionPass.h"
  17. #include "llvm/CodeGen/MachineInstrBuilder.h"
  18. #include "llvm/Support/CommandLine.h"
  19. #include "llvm/Target/TargetMachine.h"
  20. #include "llvm/Target/TargetInstrInfo.h"
  21. #include "llvm/Target/TargetRegisterInfo.h"
  22. #include "llvm/ADT/SmallSet.h"
  23. #include "llvm/ADT/Statistic.h"
  24. using namespace llvm;
  25. STATISTIC(FilledSlots, "Number of delay slots filled");
  26. static cl::opt<bool> DisableDelaySlotFiller(
  27. "disable-sparc-delay-filler",
  28. cl::init(false),
  29. cl::desc("Disable the Sparc delay slot filler."),
  30. cl::Hidden);
  31. namespace {
  32. struct Filler : public MachineFunctionPass {
  33. /// Target machine description which we query for reg. names, data
  34. /// layout, etc.
  35. ///
  36. TargetMachine &TM;
  37. const TargetInstrInfo *TII;
  38. static char ID;
  39. Filler(TargetMachine &tm)
  40. : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
  41. virtual const char *getPassName() const {
  42. return "SPARC Delay Slot Filler";
  43. }
  44. bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
  45. bool runOnMachineFunction(MachineFunction &F) {
  46. bool Changed = false;
  47. for (MachineFunction::iterator FI = F.begin(), FE = F.end();
  48. FI != FE; ++FI)
  49. Changed |= runOnMachineBasicBlock(*FI);
  50. return Changed;
  51. }
  52. bool isDelayFiller(MachineBasicBlock &MBB,
  53. MachineBasicBlock::iterator candidate);
  54. void insertCallUses(MachineBasicBlock::iterator MI,
  55. SmallSet<unsigned, 32>& RegUses);
  56. void insertDefsUses(MachineBasicBlock::iterator MI,
  57. SmallSet<unsigned, 32>& RegDefs,
  58. SmallSet<unsigned, 32>& RegUses);
  59. bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
  60. unsigned Reg);
  61. bool delayHasHazard(MachineBasicBlock::iterator candidate,
  62. bool &sawLoad, bool &sawStore,
  63. SmallSet<unsigned, 32> &RegDefs,
  64. SmallSet<unsigned, 32> &RegUses);
  65. MachineBasicBlock::iterator
  66. findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot);
  67. bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize);
  68. };
  69. char Filler::ID = 0;
  70. } // end of anonymous namespace
  71. /// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
  72. /// slots in Sparc MachineFunctions
  73. ///
  74. FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) {
  75. return new Filler(tm);
  76. }
  77. /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
  78. /// We assume there is only one delay slot per delayed instruction.
  79. ///
  80. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  81. bool Changed = false;
  82. for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
  83. if (I->hasDelaySlot()) {
  84. MachineBasicBlock::iterator D = MBB.end();
  85. MachineBasicBlock::iterator J = I;
  86. if (!DisableDelaySlotFiller)
  87. D = findDelayInstr(MBB, I);
  88. ++FilledSlots;
  89. Changed = true;
  90. if (D == MBB.end())
  91. BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(SP::NOP));
  92. else
  93. MBB.splice(++J, &MBB, D);
  94. unsigned structSize = 0;
  95. if (needsUnimp(I, structSize)) {
  96. MachineBasicBlock::iterator J = I;
  97. ++J; //skip the delay filler.
  98. BuildMI(MBB, ++J, I->getDebugLoc(),
  99. TII->get(SP::UNIMP)).addImm(structSize);
  100. }
  101. }
  102. return Changed;
  103. }
  104. MachineBasicBlock::iterator
  105. Filler::findDelayInstr(MachineBasicBlock &MBB,
  106. MachineBasicBlock::iterator slot)
  107. {
  108. SmallSet<unsigned, 32> RegDefs;
  109. SmallSet<unsigned, 32> RegUses;
  110. bool sawLoad = false;
  111. bool sawStore = false;
  112. MachineBasicBlock::iterator I = slot;
  113. if (slot->getOpcode() == SP::RET)
  114. return MBB.end();
  115. if (slot->getOpcode() == SP::RETL) {
  116. --I;
  117. if (I->getOpcode() != SP::RESTORErr)
  118. return MBB.end();
  119. //change retl to ret
  120. slot->setDesc(TII->get(SP::RET));
  121. return I;
  122. }
  123. //Call's delay filler can def some of call's uses.
  124. if (slot->isCall())
  125. insertCallUses(slot, RegUses);
  126. else
  127. insertDefsUses(slot, RegDefs, RegUses);
  128. bool done = false;
  129. while (!done) {
  130. done = (I == MBB.begin());
  131. if (!done)
  132. --I;
  133. // skip debug value
  134. if (I->isDebugValue())
  135. continue;
  136. if (I->hasUnmodeledSideEffects()
  137. || I->isInlineAsm()
  138. || I->isLabel()
  139. || I->hasDelaySlot()
  140. || isDelayFiller(MBB, I))
  141. break;
  142. if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
  143. insertDefsUses(I, RegDefs, RegUses);
  144. continue;
  145. }
  146. return I;
  147. }
  148. return MBB.end();
  149. }
  150. bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
  151. bool &sawLoad,
  152. bool &sawStore,
  153. SmallSet<unsigned, 32> &RegDefs,
  154. SmallSet<unsigned, 32> &RegUses)
  155. {
  156. if (candidate->isImplicitDef() || candidate->isKill())
  157. return true;
  158. if (candidate->mayLoad()) {
  159. sawLoad = true;
  160. if (sawStore)
  161. return true;
  162. }
  163. if (candidate->mayStore()) {
  164. if (sawStore)
  165. return true;
  166. sawStore = true;
  167. if (sawLoad)
  168. return true;
  169. }
  170. for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
  171. const MachineOperand &MO = candidate->getOperand(i);
  172. if (!MO.isReg())
  173. continue; // skip
  174. unsigned Reg = MO.getReg();
  175. if (MO.isDef()) {
  176. //check whether Reg is defined or used before delay slot.
  177. if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
  178. return true;
  179. }
  180. if (MO.isUse()) {
  181. //check whether Reg is defined before delay slot.
  182. if (IsRegInSet(RegDefs, Reg))
  183. return true;
  184. }
  185. }
  186. return false;
  187. }
  188. void Filler::insertCallUses(MachineBasicBlock::iterator MI,
  189. SmallSet<unsigned, 32>& RegUses)
  190. {
  191. switch(MI->getOpcode()) {
  192. default: llvm_unreachable("Unknown opcode.");
  193. case SP::CALL: break;
  194. case SP::JMPLrr:
  195. case SP::JMPLri:
  196. assert(MI->getNumOperands() >= 2);
  197. const MachineOperand &Reg = MI->getOperand(0);
  198. assert(Reg.isReg() && "JMPL first operand is not a register.");
  199. assert(Reg.isUse() && "JMPL first operand is not a use.");
  200. RegUses.insert(Reg.getReg());
  201. const MachineOperand &RegOrImm = MI->getOperand(1);
  202. if (RegOrImm.isImm())
  203. break;
  204. assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
  205. assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
  206. RegUses.insert(RegOrImm.getReg());
  207. break;
  208. }
  209. }
  210. //Insert Defs and Uses of MI into the sets RegDefs and RegUses.
  211. void Filler::insertDefsUses(MachineBasicBlock::iterator MI,
  212. SmallSet<unsigned, 32>& RegDefs,
  213. SmallSet<unsigned, 32>& RegUses)
  214. {
  215. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
  216. const MachineOperand &MO = MI->getOperand(i);
  217. if (!MO.isReg())
  218. continue;
  219. unsigned Reg = MO.getReg();
  220. if (Reg == 0)
  221. continue;
  222. if (MO.isDef())
  223. RegDefs.insert(Reg);
  224. if (MO.isUse())
  225. RegUses.insert(Reg);
  226. }
  227. }
  228. //returns true if the Reg or its alias is in the RegSet.
  229. bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)
  230. {
  231. if (RegSet.count(Reg))
  232. return true;
  233. // check Aliased Registers
  234. for (const uint16_t *Alias = TM.getRegisterInfo()->getAliasSet(Reg);
  235. *Alias; ++ Alias)
  236. if (RegSet.count(*Alias))
  237. return true;
  238. return false;
  239. }
  240. // return true if the candidate is a delay filler.
  241. bool Filler::isDelayFiller(MachineBasicBlock &MBB,
  242. MachineBasicBlock::iterator candidate)
  243. {
  244. if (candidate == MBB.begin())
  245. return false;
  246. if (candidate->getOpcode() == SP::UNIMP)
  247. return true;
  248. --candidate;
  249. return candidate->hasDelaySlot();
  250. }
  251. bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
  252. {
  253. if (!I->isCall())
  254. return false;
  255. unsigned structSizeOpNum = 0;
  256. switch (I->getOpcode()) {
  257. default: llvm_unreachable("Unknown call opcode.");
  258. case SP::CALL: structSizeOpNum = 1; break;
  259. case SP::JMPLrr:
  260. case SP::JMPLri: structSizeOpNum = 2; break;
  261. }
  262. const MachineOperand &MO = I->getOperand(structSizeOpNum);
  263. if (!MO.isImm())
  264. return false;
  265. StructSize = MO.getImm();
  266. return true;
  267. }