Hexagon backend support
[oota-llvm.git] / lib / Target / Hexagon / HexagonOptimizeSZExtends.cpp
1 //===-- HexagonOptimizeSZExtends.cpp - Identify and remove sign and -------===//
2 //===--                                zero extends.                -------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "llvm/Constants.h"
12 #include "llvm/PassSupport.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/Statistic.h"
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/CodeGen/MachineDominators.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineLoopInfo.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Target/TargetInstrInfo.h"
27 #include <algorithm>
28 #include "Hexagon.h"
29 #include "HexagonTargetMachine.h"
30
31 using namespace llvm;
32
33 namespace {
34   struct HexagonOptimizeSZExtends : public MachineFunctionPass {
35
36   public:
37     static char ID;
38     HexagonOptimizeSZExtends() : MachineFunctionPass(ID) {}
39
40     bool runOnMachineFunction(MachineFunction &MF);
41
42     const char *getPassName() const {
43       return "Hexagon remove redundant zero and size extends";
44     }
45
46     void getAnalysisUsage(AnalysisUsage &AU) const {
47       AU.addRequired<MachineFunctionAnalysis>();
48       AU.addPreserved<MachineFunctionAnalysis>();
49       MachineFunctionPass::getAnalysisUsage(AU);
50     }
51
52   private:
53   };
54 }
55
56 char HexagonOptimizeSZExtends::ID = 0;
57
58 // This is a brain dead pass to get rid of redundant sign extends for the
59 // following case:
60 //
61 // Transform the following pattern
62 // %vreg170<def> = SXTW %vreg166
63 // ...
64 // %vreg176<def> = COPY %vreg170:subreg_loreg
65 //
66 // Into
67 // %vreg176<def> = COPY vreg166
68
69 bool HexagonOptimizeSZExtends::runOnMachineFunction(MachineFunction &MF) {
70   DenseMap<unsigned, unsigned> SExtMap;
71
72   // Loop over all of the basic blocks
73   for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
74        MBBb != MBBe; ++MBBb) {
75     MachineBasicBlock* MBB = MBBb;
76     SExtMap.clear();
77
78     // Traverse the basic block.
79     for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
80          ++MII) {
81       MachineInstr *MI = MII;
82       // Look for sign extends:
83       //   %vreg170<def> = SXTW %vreg166
84       if (MI->getOpcode() == Hexagon::SXTW) {
85         assert (MI->getNumOperands() == 2);
86         MachineOperand &Dst = MI->getOperand(0);
87         MachineOperand &Src  = MI->getOperand(1);
88         unsigned DstReg = Dst.getReg();
89         unsigned SrcReg = Src.getReg();
90         // Just handle virtual registers.
91         if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
92             TargetRegisterInfo::isVirtualRegister(SrcReg)) {
93           // Map the following:
94           //  %vreg170<def> = SXTW %vreg166
95           //  SExtMap[170] = vreg166
96           SExtMap[DstReg] = SrcReg;
97         }
98       }
99       // Look for copy:
100       //   %vreg176<def> = COPY %vreg170:subreg_loreg
101       if (MI->isCopy()) {
102         assert (MI->getNumOperands() == 2);
103         MachineOperand &Dst = MI->getOperand(0);
104         MachineOperand &Src  = MI->getOperand(1);
105
106         // Make sure we are copying the lower 32 bits.
107         if (Src.getSubReg() != Hexagon::subreg_loreg)
108           continue;
109
110         unsigned DstReg = Dst.getReg();
111         unsigned SrcReg = Src.getReg();
112         if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
113             TargetRegisterInfo::isVirtualRegister(SrcReg)) {
114           // Try to find in the map.
115           if (unsigned SextSrc = SExtMap.lookup(SrcReg)) {
116             // Change the 1st operand.
117             MI->RemoveOperand(1);
118             MI->addOperand(MachineOperand::CreateReg(SextSrc, false));
119           }
120         }
121       }
122     }
123   }
124   return true;
125 }
126
127 FunctionPass *llvm::createHexagonOptimizeSZExtends() {
128   return new HexagonOptimizeSZExtends();
129 }