Bug Summary

File:lib/Target/Hexagon/HexagonFixupHwLoops.cpp
Location:line 131, column 3
Description:Value stored to 'InstOffset' is never read

Annotated Source Code

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 instruction needs to use a constant extender.
11// This pass will identify and convert such LOOPn instructions to a proper
12// form.
13//===----------------------------------------------------------------------===//
14
15
16#include "llvm/ADT/DenseMap.h"
17#include "Hexagon.h"
18#include "HexagonTargetMachine.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/Passes.h"
23#include "llvm/PassSupport.h"
24#include "llvm/Target/TargetInstrInfo.h"
25
26using namespace llvm;
27
28static cl::opt<unsigned> MaxLoopRange(
29 "hexagon-loop-range", cl::Hidden, cl::init(200),
30 cl::desc("Restrict range of loopN instructions (testing only)"));
31
32namespace llvm {
33 FunctionPass *createHexagonFixupHwLoops();
34 void initializeHexagonFixupHwLoopsPass(PassRegistry&);
35}
36
37namespace {
38 struct HexagonFixupHwLoops : public MachineFunctionPass {
39 public:
40 static char ID;
41
42 HexagonFixupHwLoops() : MachineFunctionPass(ID) {
43 initializeHexagonFixupHwLoopsPass(*PassRegistry::getPassRegistry());
44 }
45
46 bool runOnMachineFunction(MachineFunction &MF) override;
47
48 MachineFunctionProperties getRequiredProperties() const override {
49 return MachineFunctionProperties().set(
50 MachineFunctionProperties::Property::AllVRegsAllocated);
51 }
52
53 const char *getPassName() const override {
54 return "Hexagon Hardware Loop Fixup";
55 }
56
57 void getAnalysisUsage(AnalysisUsage &AU) const override {
58 AU.setPreservesCFG();
59 MachineFunctionPass::getAnalysisUsage(AU);
60 }
61
62 private:
63 /// \brief Check the offset between each loop instruction and
64 /// the loop basic block to determine if we can use the LOOP instruction
65 /// or if we need to set the LC/SA registers explicitly.
66 bool fixupLoopInstrs(MachineFunction &MF);
67
68 /// \brief Replace loop instruction with the constant extended
69 /// version if the loop label is too far from the loop instruction.
70 void useExtLoopInstr(MachineFunction &MF,
71 MachineBasicBlock::iterator &MII);
72 };
73
74 char HexagonFixupHwLoops::ID = 0;
75}
76
77INITIALIZE_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(); ; ; initialized = 2; ; } else
{ sys::cas_flag tmp = initialized; sys::MemoryFence(); while
(tmp != 2) { tmp = initialized; sys::MemoryFence(); } } ; }
78 "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(); ; ; initialized = 2; ; } else
{ sys::cas_flag tmp = initialized; sys::MemoryFence(); while
(tmp != 2) { tmp = initialized; sys::MemoryFence(); } } ; }
79
80FunctionPass *llvm::createHexagonFixupHwLoops() {
81 return new HexagonFixupHwLoops();
82}
83
84/// \brief Returns true if the instruction is a hardware loop instruction.
85static bool isHardwareLoop(const MachineInstr *MI) {
86 return MI->getOpcode() == Hexagon::J2_loop0r ||
87 MI->getOpcode() == Hexagon::J2_loop0i ||
88 MI->getOpcode() == Hexagon::J2_loop1r ||
89 MI->getOpcode() == Hexagon::J2_loop1i;
90}
91
92bool HexagonFixupHwLoops::runOnMachineFunction(MachineFunction &MF) {
93 return fixupLoopInstrs(MF);
94}
95
96/// \brief For Hexagon, if the loop label is to far from the
97/// loop instruction then we need to set the LC0 and SA0 registers
98/// explicitly instead of using LOOP(start,count). This function
99/// checks the distance, and generates register assignments if needed.
100///
101/// This function makes two passes over the basic blocks. The first
102/// pass computes the offset of the basic block from the start.
103/// The second pass checks all the loop instructions.
104bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
105
106 // Offset of the current instruction from the start.
107 unsigned InstOffset = 0;
108 // Map for each basic block to it's first instruction.
109 DenseMap<const MachineBasicBlock *, unsigned> BlockToInstOffset;
110
111 const HexagonInstrInfo *HII =
112 static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
113
114 // First pass - compute the offset of each basic block.
115 for (const MachineBasicBlock &MBB : MF) {
116 if (MBB.getAlignment()) {
117 // Although we don't know the exact layout of the final code, we need
118 // to account for alignment padding somehow. This heuristic pads each
119 // aligned basic block according to the alignment value.
120 int ByteAlign = (1u << MBB.getAlignment()) - 1;
121 InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
122 }
123
124 BlockToInstOffset[&MBB] = InstOffset;
125 for (const MachineInstr &MI : MBB)
126 InstOffset += HII->getSize(&MI);
127 }
128
129 // Second pass - check each loop instruction to see if it needs to be
130 // converted.
131 InstOffset = 0;
Value stored to 'InstOffset' is never read
132 bool Changed = false;
133 for (MachineBasicBlock &MBB : MF) {
134 InstOffset = BlockToInstOffset[&MBB];
135
136 // Loop over all the instructions.
137 MachineBasicBlock::iterator MII = MBB.begin();
138 MachineBasicBlock::iterator MIE = MBB.end();
139 while (MII != MIE) {
140 InstOffset += HII->getSize(&*MII);
141 if (MII->isDebugValue()) {
142 ++MII;
143 continue;
144 }
145 if (isHardwareLoop(MII)) {
146 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.9~svn267387/lib/Target/Hexagon/HexagonFixupHwLoops.cpp"
, 147, __PRETTY_FUNCTION__))
147 "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.9~svn267387/lib/Target/Hexagon/HexagonFixupHwLoops.cpp"
, 147, __PRETTY_FUNCTION__))
;
148 int diff = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()];
149 if ((unsigned)abs(diff) > MaxLoopRange) {
150 useExtLoopInstr(MF, MII);
151 MII = MBB.erase(MII);
152 Changed = true;
153 } else {
154 ++MII;
155 }
156 } else {
157 ++MII;
158 }
159 }
160 }
161
162 return Changed;
163}
164
165/// \brief Replace loop instructions with the constant extended version.
166void HexagonFixupHwLoops::useExtLoopInstr(MachineFunction &MF,
167 MachineBasicBlock::iterator &MII) {
168 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
169 MachineBasicBlock *MBB = MII->getParent();
170 DebugLoc DL = MII->getDebugLoc();
171 MachineInstrBuilder MIB;
172 unsigned newOp;
173 switch (MII->getOpcode()) {
174 case Hexagon::J2_loop0r:
175 newOp = Hexagon::J2_loop0rext;
176 break;
177 case Hexagon::J2_loop0i:
178 newOp = Hexagon::J2_loop0iext;
179 break;
180 case Hexagon::J2_loop1r:
181 newOp = Hexagon::J2_loop1rext;
182 break;
183 case Hexagon::J2_loop1i:
184 newOp = Hexagon::J2_loop1iext;
185 break;
186 default:
187 llvm_unreachable("Invalid Hardware Loop Instruction.")::llvm::llvm_unreachable_internal("Invalid Hardware Loop Instruction."
, "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn267387/lib/Target/Hexagon/HexagonFixupHwLoops.cpp"
, 187)
;
188 }
189 MIB = BuildMI(*MBB, MII, DL, TII->get(newOp));
190
191 for (unsigned i = 0; i < MII->getNumOperands(); ++i)
192 MIB.addOperand(MII->getOperand(i));
193}