PageRenderTime 352ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Target/Hexagon/HexagonPeephole.cpp

https://gitlab.com/Birhetia/platform_external_llvm
C++ | 338 lines | 234 code | 38 blank | 66 comment | 55 complexity | 82a9f5b44cf8372265eda6e46966e506 MD5 | raw file
  1. //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
  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. // This peephole pass optimizes in the following cases.
  9. // 1. Optimizes redundant sign extends for the following case
  10. // Transform the following pattern
  11. // %vreg170<def> = SXTW %vreg166
  12. // ...
  13. // %vreg176<def> = COPY %vreg170:subreg_loreg
  14. //
  15. // Into
  16. // %vreg176<def> = COPY vreg166
  17. //
  18. // 2. Optimizes redundant negation of predicates.
  19. // %vreg15<def> = CMPGTrr %vreg6, %vreg2
  20. // ...
  21. // %vreg16<def> = NOT_p %vreg15<kill>
  22. // ...
  23. // JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead>
  24. //
  25. // Into
  26. // %vreg15<def> = CMPGTrr %vreg6, %vreg2;
  27. // ...
  28. // JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>;
  29. //
  30. // Note: The peephole pass makes the instrucstions like
  31. // %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill>
  32. // redundant and relies on some form of dead removal instructions, like
  33. // DCE or DIE to actually eliminate them.
  34. //===----------------------------------------------------------------------===//
  35. #include "Hexagon.h"
  36. #include "HexagonTargetMachine.h"
  37. #include "llvm/ADT/DenseMap.h"
  38. #include "llvm/ADT/Statistic.h"
  39. #include "llvm/CodeGen/MachineFunction.h"
  40. #include "llvm/CodeGen/MachineFunctionPass.h"
  41. #include "llvm/CodeGen/MachineInstrBuilder.h"
  42. #include "llvm/CodeGen/MachineRegisterInfo.h"
  43. #include "llvm/CodeGen/Passes.h"
  44. #include "llvm/IR/Constants.h"
  45. #include "llvm/PassSupport.h"
  46. #include "llvm/Support/CommandLine.h"
  47. #include "llvm/Support/Debug.h"
  48. #include "llvm/Support/raw_ostream.h"
  49. #include "llvm/Target/TargetInstrInfo.h"
  50. #include "llvm/Target/TargetMachine.h"
  51. #include "llvm/Target/TargetRegisterInfo.h"
  52. #include <algorithm>
  53. using namespace llvm;
  54. #define DEBUG_TYPE "hexagon-peephole"
  55. static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
  56. cl::Hidden, cl::ZeroOrMore, cl::init(false),
  57. cl::desc("Disable Peephole Optimization"));
  58. static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
  59. cl::Hidden, cl::ZeroOrMore, cl::init(false),
  60. cl::desc("Disable Optimization of PNotP"));
  61. static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
  62. cl::Hidden, cl::ZeroOrMore, cl::init(false),
  63. cl::desc("Disable Optimization of Sign/Zero Extends"));
  64. static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
  65. cl::Hidden, cl::ZeroOrMore, cl::init(false),
  66. cl::desc("Disable Optimization of extensions to i64."));
  67. namespace llvm {
  68. FunctionPass *createHexagonPeephole();
  69. void initializeHexagonPeepholePass(PassRegistry&);
  70. }
  71. namespace {
  72. struct HexagonPeephole : public MachineFunctionPass {
  73. const HexagonInstrInfo *QII;
  74. const HexagonRegisterInfo *QRI;
  75. const MachineRegisterInfo *MRI;
  76. public:
  77. static char ID;
  78. HexagonPeephole() : MachineFunctionPass(ID) {
  79. initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
  80. }
  81. bool runOnMachineFunction(MachineFunction &MF) override;
  82. const char *getPassName() const override {
  83. return "Hexagon optimize redundant zero and size extends";
  84. }
  85. void getAnalysisUsage(AnalysisUsage &AU) const override {
  86. MachineFunctionPass::getAnalysisUsage(AU);
  87. }
  88. private:
  89. void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src);
  90. };
  91. }
  92. char HexagonPeephole::ID = 0;
  93. INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
  94. false, false)
  95. bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
  96. QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
  97. QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
  98. MRI = &MF.getRegInfo();
  99. DenseMap<unsigned, unsigned> PeepholeMap;
  100. DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
  101. if (DisableHexagonPeephole) return false;
  102. // Loop over all of the basic blocks.
  103. for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
  104. MBBb != MBBe; ++MBBb) {
  105. MachineBasicBlock *MBB = &*MBBb;
  106. PeepholeMap.clear();
  107. PeepholeDoubleRegsMap.clear();
  108. // Traverse the basic block.
  109. for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
  110. ++MII) {
  111. MachineInstr *MI = MII;
  112. // Look for sign extends:
  113. // %vreg170<def> = SXTW %vreg166
  114. if (!DisableOptSZExt && MI->getOpcode() == Hexagon::A2_sxtw) {
  115. assert (MI->getNumOperands() == 2);
  116. MachineOperand &Dst = MI->getOperand(0);
  117. MachineOperand &Src = MI->getOperand(1);
  118. unsigned DstReg = Dst.getReg();
  119. unsigned SrcReg = Src.getReg();
  120. // Just handle virtual registers.
  121. if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
  122. TargetRegisterInfo::isVirtualRegister(SrcReg)) {
  123. // Map the following:
  124. // %vreg170<def> = SXTW %vreg166
  125. // PeepholeMap[170] = vreg166
  126. PeepholeMap[DstReg] = SrcReg;
  127. }
  128. }
  129. // Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
  130. // %vreg170:DoublRegs, %vreg169:IntRegs
  131. if (!DisableOptExtTo64 &&
  132. MI->getOpcode () == Hexagon::A4_combineir) {
  133. assert (MI->getNumOperands() == 3);
  134. MachineOperand &Dst = MI->getOperand(0);
  135. MachineOperand &Src1 = MI->getOperand(1);
  136. MachineOperand &Src2 = MI->getOperand(2);
  137. if (Src1.getImm() != 0)
  138. continue;
  139. unsigned DstReg = Dst.getReg();
  140. unsigned SrcReg = Src2.getReg();
  141. PeepholeMap[DstReg] = SrcReg;
  142. }
  143. // Look for this sequence below
  144. // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
  145. // %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
  146. // and convert into
  147. // %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
  148. if (MI->getOpcode() == Hexagon::S2_lsr_i_p) {
  149. assert(MI->getNumOperands() == 3);
  150. MachineOperand &Dst = MI->getOperand(0);
  151. MachineOperand &Src1 = MI->getOperand(1);
  152. MachineOperand &Src2 = MI->getOperand(2);
  153. if (Src2.getImm() != 32)
  154. continue;
  155. unsigned DstReg = Dst.getReg();
  156. unsigned SrcReg = Src1.getReg();
  157. PeepholeDoubleRegsMap[DstReg] =
  158. std::make_pair(*&SrcReg, Hexagon::subreg_hireg);
  159. }
  160. // Look for P=NOT(P).
  161. if (!DisablePNotP &&
  162. (MI->getOpcode() == Hexagon::C2_not)) {
  163. assert (MI->getNumOperands() == 2);
  164. MachineOperand &Dst = MI->getOperand(0);
  165. MachineOperand &Src = MI->getOperand(1);
  166. unsigned DstReg = Dst.getReg();
  167. unsigned SrcReg = Src.getReg();
  168. // Just handle virtual registers.
  169. if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
  170. TargetRegisterInfo::isVirtualRegister(SrcReg)) {
  171. // Map the following:
  172. // %vreg170<def> = NOT_xx %vreg166
  173. // PeepholeMap[170] = vreg166
  174. PeepholeMap[DstReg] = SrcReg;
  175. }
  176. }
  177. // Look for copy:
  178. // %vreg176<def> = COPY %vreg170:subreg_loreg
  179. if (!DisableOptSZExt && MI->isCopy()) {
  180. assert (MI->getNumOperands() == 2);
  181. MachineOperand &Dst = MI->getOperand(0);
  182. MachineOperand &Src = MI->getOperand(1);
  183. // Make sure we are copying the lower 32 bits.
  184. if (Src.getSubReg() != Hexagon::subreg_loreg)
  185. continue;
  186. unsigned DstReg = Dst.getReg();
  187. unsigned SrcReg = Src.getReg();
  188. if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
  189. TargetRegisterInfo::isVirtualRegister(SrcReg)) {
  190. // Try to find in the map.
  191. if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
  192. // Change the 1st operand.
  193. MI->RemoveOperand(1);
  194. MI->addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
  195. } else {
  196. DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
  197. PeepholeDoubleRegsMap.find(SrcReg);
  198. if (DI != PeepholeDoubleRegsMap.end()) {
  199. std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
  200. MI->RemoveOperand(1);
  201. MI->addOperand(MachineOperand::CreateReg(PeepholeSrc.first,
  202. false /*isDef*/,
  203. false /*isImp*/,
  204. false /*isKill*/,
  205. false /*isDead*/,
  206. false /*isUndef*/,
  207. false /*isEarlyClobber*/,
  208. PeepholeSrc.second));
  209. }
  210. }
  211. }
  212. }
  213. // Look for Predicated instructions.
  214. if (!DisablePNotP) {
  215. bool Done = false;
  216. if (QII->isPredicated(MI)) {
  217. MachineOperand &Op0 = MI->getOperand(0);
  218. unsigned Reg0 = Op0.getReg();
  219. const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
  220. if (RC0->getID() == Hexagon::PredRegsRegClassID) {
  221. // Handle instructions that have a prediate register in op0
  222. // (most cases of predicable instructions).
  223. if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
  224. // Try to find in the map.
  225. if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
  226. // Change the 1st operand and, flip the opcode.
  227. MI->getOperand(0).setReg(PeepholeSrc);
  228. int NewOp = QII->getInvertedPredicatedOpcode(MI->getOpcode());
  229. MI->setDesc(QII->get(NewOp));
  230. Done = true;
  231. }
  232. }
  233. }
  234. }
  235. if (!Done) {
  236. // Handle special instructions.
  237. unsigned Op = MI->getOpcode();
  238. unsigned NewOp = 0;
  239. unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
  240. switch (Op) {
  241. case Hexagon::C2_mux:
  242. case Hexagon::C2_muxii:
  243. NewOp = Op;
  244. break;
  245. case Hexagon::C2_muxri:
  246. NewOp = Hexagon::C2_muxir;
  247. break;
  248. case Hexagon::C2_muxir:
  249. NewOp = Hexagon::C2_muxri;
  250. break;
  251. }
  252. if (NewOp) {
  253. unsigned PSrc = MI->getOperand(PR).getReg();
  254. if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
  255. MI->getOperand(PR).setReg(POrig);
  256. MI->setDesc(QII->get(NewOp));
  257. // Swap operands S1 and S2.
  258. MachineOperand Op1 = MI->getOperand(S1);
  259. MachineOperand Op2 = MI->getOperand(S2);
  260. ChangeOpInto(MI->getOperand(S1), Op2);
  261. ChangeOpInto(MI->getOperand(S2), Op1);
  262. }
  263. } // if (NewOp)
  264. } // if (!Done)
  265. } // if (!DisablePNotP)
  266. } // Instruction
  267. } // Basic Block
  268. return true;
  269. }
  270. void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
  271. assert (&Dst != &Src && "Cannot duplicate into itself");
  272. switch (Dst.getType()) {
  273. case MachineOperand::MO_Register:
  274. if (Src.isReg()) {
  275. Dst.setReg(Src.getReg());
  276. } else if (Src.isImm()) {
  277. Dst.ChangeToImmediate(Src.getImm());
  278. } else {
  279. llvm_unreachable("Unexpected src operand type");
  280. }
  281. break;
  282. case MachineOperand::MO_Immediate:
  283. if (Src.isImm()) {
  284. Dst.setImm(Src.getImm());
  285. } else if (Src.isReg()) {
  286. Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
  287. Src.isKill(), Src.isDead(), Src.isUndef(),
  288. Src.isDebug());
  289. } else {
  290. llvm_unreachable("Unexpected src operand type");
  291. }
  292. break;
  293. default:
  294. llvm_unreachable("Unexpected dst operand type");
  295. break;
  296. }
  297. }
  298. FunctionPass *llvm::createHexagonPeephole() {
  299. return new HexagonPeephole();
  300. }