File: | lib/Target/Hexagon/HexagonFixupHwLoops.cpp |
Location: | line 119, column 3 |
Description: | Value stored to 'InstOffset' is never read |
1 | //===---- HexagonFixupHwLoops.cpp - Fixup HW loops too far from LOOPn. ----===// |
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 | // The loop start address in the LOOPn instruction is encoded as a distance |
9 | // from the LOOPn instruction itself. If the start address is too far from |
10 | // the LOOPn instruction, the loop needs to be set up manually, i.e. via |
11 | // direct transfers to SAn and LCn. |
12 | // This pass will identify and convert such LOOPn instructions to a proper |
13 | // form. |
14 | //===----------------------------------------------------------------------===// |
15 | |
16 | |
17 | #include "llvm/ADT/DenseMap.h" |
18 | #include "Hexagon.h" |
19 | #include "HexagonTargetMachine.h" |
20 | #include "llvm/CodeGen/MachineFunction.h" |
21 | #include "llvm/CodeGen/MachineFunctionPass.h" |
22 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
23 | #include "llvm/CodeGen/Passes.h" |
24 | #include "llvm/CodeGen/RegisterScavenging.h" |
25 | #include "llvm/PassSupport.h" |
26 | #include "llvm/Target/TargetInstrInfo.h" |
27 | |
28 | using namespace llvm; |
29 | |
30 | namespace llvm { |
31 | void initializeHexagonFixupHwLoopsPass(PassRegistry&); |
32 | } |
33 | |
34 | namespace { |
35 | struct HexagonFixupHwLoops : public MachineFunctionPass { |
36 | public: |
37 | static char ID; |
38 | |
39 | HexagonFixupHwLoops() : MachineFunctionPass(ID) { |
40 | initializeHexagonFixupHwLoopsPass(*PassRegistry::getPassRegistry()); |
41 | } |
42 | |
43 | bool runOnMachineFunction(MachineFunction &MF) override; |
44 | |
45 | const char *getPassName() const override { |
46 | return "Hexagon Hardware Loop Fixup"; |
47 | } |
48 | |
49 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
50 | AU.setPreservesCFG(); |
51 | MachineFunctionPass::getAnalysisUsage(AU); |
52 | } |
53 | |
54 | private: |
55 | /// \brief Maximum distance between the loop instr and the basic block. |
56 | /// Just an estimate. |
57 | static const unsigned MAX_LOOP_DISTANCE = 200; |
58 | |
59 | /// \brief Check the offset between each loop instruction and |
60 | /// the loop basic block to determine if we can use the LOOP instruction |
61 | /// or if we need to set the LC/SA registers explicitly. |
62 | bool fixupLoopInstrs(MachineFunction &MF); |
63 | |
64 | /// \brief Add the instruction to set the LC and SA registers explicitly. |
65 | void convertLoopInstr(MachineFunction &MF, |
66 | MachineBasicBlock::iterator &MII, |
67 | RegScavenger &RS); |
68 | |
69 | }; |
70 | |
71 | char HexagonFixupHwLoops::ID = 0; |
72 | } |
73 | |
74 | INITIALIZE_PASS(HexagonFixupHwLoops, "hwloopsfixup",static void* initializeHexagonFixupHwLoopsPassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo("Hexagon Hardware Loops Fixup" , "hwloopsfixup", & HexagonFixupHwLoops ::ID, PassInfo::NormalCtor_t (callDefaultCtor< HexagonFixupHwLoops >), false, false) ; Registry.registerPass(*PI, true); return PI; } void llvm::initializeHexagonFixupHwLoopsPass (PassRegistry &Registry) { static volatile sys::cas_flag initialized = 0; sys::cas_flag old_val = sys::CompareAndSwap(&initialized , 1, 0); if (old_val == 0) { initializeHexagonFixupHwLoopsPassOnce (Registry); sys::MemoryFence(); AnnotateIgnoreWritesBegin("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75); AnnotateHappensBefore("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75, &initialized); initialized = 2; AnnotateIgnoreWritesEnd ("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75); } else { sys::cas_flag tmp = initialized; sys::MemoryFence (); while (tmp != 2) { tmp = initialized; sys::MemoryFence(); } } AnnotateHappensAfter("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75, &initialized); } |
75 | "Hexagon Hardware Loops Fixup", false, false)static void* initializeHexagonFixupHwLoopsPassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo("Hexagon Hardware Loops Fixup" , "hwloopsfixup", & HexagonFixupHwLoops ::ID, PassInfo::NormalCtor_t (callDefaultCtor< HexagonFixupHwLoops >), false, false) ; Registry.registerPass(*PI, true); return PI; } void llvm::initializeHexagonFixupHwLoopsPass (PassRegistry &Registry) { static volatile sys::cas_flag initialized = 0; sys::cas_flag old_val = sys::CompareAndSwap(&initialized , 1, 0); if (old_val == 0) { initializeHexagonFixupHwLoopsPassOnce (Registry); sys::MemoryFence(); AnnotateIgnoreWritesBegin("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75); AnnotateHappensBefore("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75, &initialized); initialized = 2; AnnotateIgnoreWritesEnd ("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75); } else { sys::cas_flag tmp = initialized; sys::MemoryFence (); while (tmp != 2) { tmp = initialized; sys::MemoryFence(); } } AnnotateHappensAfter("/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 75, &initialized); } |
76 | |
77 | FunctionPass *llvm::createHexagonFixupHwLoops() { |
78 | return new HexagonFixupHwLoops(); |
79 | } |
80 | |
81 | |
82 | /// \brief Returns true if the instruction is a hardware loop instruction. |
83 | static bool isHardwareLoop(const MachineInstr *MI) { |
84 | return MI->getOpcode() == Hexagon::J2_loop0r || |
85 | MI->getOpcode() == Hexagon::J2_loop0i; |
86 | } |
87 | |
88 | |
89 | bool HexagonFixupHwLoops::runOnMachineFunction(MachineFunction &MF) { |
90 | bool Changed = fixupLoopInstrs(MF); |
91 | return Changed; |
92 | } |
93 | |
94 | |
95 | /// \brief For Hexagon, if the loop label is to far from the |
96 | /// loop instruction then we need to set the LC0 and SA0 registers |
97 | /// explicitly instead of using LOOP(start,count). This function |
98 | /// checks the distance, and generates register assignments if needed. |
99 | /// |
100 | /// This function makes two passes over the basic blocks. The first |
101 | /// pass computes the offset of the basic block from the start. |
102 | /// The second pass checks all the loop instructions. |
103 | bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) { |
104 | |
105 | // Offset of the current instruction from the start. |
106 | unsigned InstOffset = 0; |
107 | // Map for each basic block to it's first instruction. |
108 | DenseMap<MachineBasicBlock*, unsigned> BlockToInstOffset; |
109 | |
110 | // First pass - compute the offset of each basic block. |
111 | for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); |
112 | MBB != MBBe; ++MBB) { |
113 | BlockToInstOffset[MBB] = InstOffset; |
114 | InstOffset += (MBB->size() * 4); |
115 | } |
116 | |
117 | // Second pass - check each loop instruction to see if it needs to |
118 | // be converted. |
119 | InstOffset = 0; |
Value stored to 'InstOffset' is never read | |
120 | bool Changed = false; |
121 | RegScavenger RS; |
122 | |
123 | // Loop over all the basic blocks. |
124 | for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); |
125 | MBB != MBBe; ++MBB) { |
126 | InstOffset = BlockToInstOffset[MBB]; |
127 | RS.enterBasicBlock(MBB); |
128 | |
129 | // Loop over all the instructions. |
130 | MachineBasicBlock::iterator MIE = MBB->end(); |
131 | MachineBasicBlock::iterator MII = MBB->begin(); |
132 | while (MII != MIE) { |
133 | if (isHardwareLoop(MII)) { |
134 | RS.forward(MII); |
135 | assert(MII->getOperand(0).isMBB() &&((MII->getOperand(0).isMBB() && "Expect a basic block as loop operand" ) ? static_cast<void> (0) : __assert_fail ("MII->getOperand(0).isMBB() && \"Expect a basic block as loop operand\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 136, __PRETTY_FUNCTION__)) |
136 | "Expect a basic block as loop operand")((MII->getOperand(0).isMBB() && "Expect a basic block as loop operand" ) ? static_cast<void> (0) : __assert_fail ("MII->getOperand(0).isMBB() && \"Expect a basic block as loop operand\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/Target/Hexagon/HexagonFixupHwLoops.cpp" , 136, __PRETTY_FUNCTION__)); |
137 | int Sub = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()]; |
138 | unsigned Dist = Sub > 0 ? Sub : -Sub; |
139 | if (Dist > MAX_LOOP_DISTANCE) { |
140 | // Convert to explicity setting LC0 and SA0. |
141 | convertLoopInstr(MF, MII, RS); |
142 | MII = MBB->erase(MII); |
143 | Changed = true; |
144 | } else { |
145 | ++MII; |
146 | } |
147 | } else { |
148 | ++MII; |
149 | } |
150 | InstOffset += 4; |
151 | } |
152 | } |
153 | |
154 | return Changed; |
155 | } |
156 | |
157 | |
158 | /// \brief convert a loop instruction to a sequence of instructions that |
159 | /// set the LC0 and SA0 register explicitly. |
160 | void HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF, |
161 | MachineBasicBlock::iterator &MII, |
162 | RegScavenger &RS) { |
163 | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); |
164 | MachineBasicBlock *MBB = MII->getParent(); |
165 | DebugLoc DL = MII->getDebugLoc(); |
166 | unsigned Scratch = RS.scavengeRegister(&Hexagon::IntRegsRegClass, MII, 0); |
167 | |
168 | // First, set the LC0 with the trip count. |
169 | if (MII->getOperand(1).isReg()) { |
170 | // Trip count is a register |
171 | BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::LC0) |
172 | .addReg(MII->getOperand(1).getReg()); |
173 | } else { |
174 | // Trip count is an immediate. |
175 | BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrsi), Scratch) |
176 | .addImm(MII->getOperand(1).getImm()); |
177 | BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::LC0) |
178 | .addReg(Scratch); |
179 | } |
180 | // Then, set the SA0 with the loop start address. |
181 | BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrsi), Scratch) |
182 | .addMBB(MII->getOperand(0).getMBB()); |
183 | BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::SA0) |
184 | .addReg(Scratch); |
185 | } |