File: | llvm/lib/Target/WebAssembly/WebAssemblyLowerBrUnless.cpp |
Warning: | line 196, column 9 Value stored to 'Inverted' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- WebAssemblyLowerBrUnless.cpp - Lower br_unless --------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// This file lowers br_unless into br_if with an inverted condition. |
11 | /// |
12 | /// br_unless is not currently in the spec, but it's very convenient for LLVM |
13 | /// to use. This pass allows LLVM to use it, for now. |
14 | /// |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" |
18 | #include "WebAssembly.h" |
19 | #include "WebAssemblyMachineFunctionInfo.h" |
20 | #include "WebAssemblySubtarget.h" |
21 | #include "llvm/CodeGen/MachineFunctionPass.h" |
22 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
23 | #include "llvm/Support/Debug.h" |
24 | #include "llvm/Support/raw_ostream.h" |
25 | using namespace llvm; |
26 | |
27 | #define DEBUG_TYPE"wasm-lower-br_unless" "wasm-lower-br_unless" |
28 | |
29 | namespace { |
30 | class WebAssemblyLowerBrUnless final : public MachineFunctionPass { |
31 | StringRef getPassName() const override { |
32 | return "WebAssembly Lower br_unless"; |
33 | } |
34 | |
35 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
36 | AU.setPreservesCFG(); |
37 | MachineFunctionPass::getAnalysisUsage(AU); |
38 | } |
39 | |
40 | bool runOnMachineFunction(MachineFunction &MF) override; |
41 | |
42 | public: |
43 | static char ID; // Pass identification, replacement for typeid |
44 | WebAssemblyLowerBrUnless() : MachineFunctionPass(ID) {} |
45 | }; |
46 | } // end anonymous namespace |
47 | |
48 | char WebAssemblyLowerBrUnless::ID = 0; |
49 | INITIALIZE_PASS(WebAssemblyLowerBrUnless, DEBUG_TYPE,static void *initializeWebAssemblyLowerBrUnlessPassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo( "Lowers br_unless into inverted br_if" , "wasm-lower-br_unless", &WebAssemblyLowerBrUnless::ID, PassInfo ::NormalCtor_t(callDefaultCtor<WebAssemblyLowerBrUnless> ), false, false); Registry.registerPass(*PI, true); return PI ; } static llvm::once_flag InitializeWebAssemblyLowerBrUnlessPassFlag ; void llvm::initializeWebAssemblyLowerBrUnlessPass(PassRegistry &Registry) { llvm::call_once(InitializeWebAssemblyLowerBrUnlessPassFlag , initializeWebAssemblyLowerBrUnlessPassOnce, std::ref(Registry )); } |
50 | "Lowers br_unless into inverted br_if", false, false)static void *initializeWebAssemblyLowerBrUnlessPassOnce(PassRegistry &Registry) { PassInfo *PI = new PassInfo( "Lowers br_unless into inverted br_if" , "wasm-lower-br_unless", &WebAssemblyLowerBrUnless::ID, PassInfo ::NormalCtor_t(callDefaultCtor<WebAssemblyLowerBrUnless> ), false, false); Registry.registerPass(*PI, true); return PI ; } static llvm::once_flag InitializeWebAssemblyLowerBrUnlessPassFlag ; void llvm::initializeWebAssemblyLowerBrUnlessPass(PassRegistry &Registry) { llvm::call_once(InitializeWebAssemblyLowerBrUnlessPassFlag , initializeWebAssemblyLowerBrUnlessPassOnce, std::ref(Registry )); } |
51 | |
52 | FunctionPass *llvm::createWebAssemblyLowerBrUnless() { |
53 | return new WebAssemblyLowerBrUnless(); |
54 | } |
55 | |
56 | bool WebAssemblyLowerBrUnless::runOnMachineFunction(MachineFunction &MF) { |
57 | LLVM_DEBUG(dbgs() << "********** Lowering br_unless **********\n"do { } while (false) |
58 | "********** Function: "do { } while (false) |
59 | << MF.getName() << '\n')do { } while (false); |
60 | |
61 | auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); |
62 | const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); |
63 | auto &MRI = MF.getRegInfo(); |
64 | |
65 | for (auto &MBB : MF) { |
66 | for (auto MII = MBB.begin(); MII != MBB.end();) { |
67 | MachineInstr *MI = &*MII++; |
68 | if (MI->getOpcode() != WebAssembly::BR_UNLESS) |
69 | continue; |
70 | |
71 | Register Cond = MI->getOperand(1).getReg(); |
72 | bool Inverted = false; |
73 | |
74 | // Attempt to invert the condition in place. |
75 | if (MFI.isVRegStackified(Cond)) { |
76 | assert(MRI.hasOneDef(Cond))(static_cast<void> (0)); |
77 | MachineInstr *Def = MRI.getVRegDef(Cond); |
78 | switch (Def->getOpcode()) { |
79 | using namespace WebAssembly; |
80 | case EQ_I32: |
81 | Def->setDesc(TII.get(NE_I32)); |
82 | Inverted = true; |
83 | break; |
84 | case NE_I32: |
85 | Def->setDesc(TII.get(EQ_I32)); |
86 | Inverted = true; |
87 | break; |
88 | case GT_S_I32: |
89 | Def->setDesc(TII.get(LE_S_I32)); |
90 | Inverted = true; |
91 | break; |
92 | case GE_S_I32: |
93 | Def->setDesc(TII.get(LT_S_I32)); |
94 | Inverted = true; |
95 | break; |
96 | case LT_S_I32: |
97 | Def->setDesc(TII.get(GE_S_I32)); |
98 | Inverted = true; |
99 | break; |
100 | case LE_S_I32: |
101 | Def->setDesc(TII.get(GT_S_I32)); |
102 | Inverted = true; |
103 | break; |
104 | case GT_U_I32: |
105 | Def->setDesc(TII.get(LE_U_I32)); |
106 | Inverted = true; |
107 | break; |
108 | case GE_U_I32: |
109 | Def->setDesc(TII.get(LT_U_I32)); |
110 | Inverted = true; |
111 | break; |
112 | case LT_U_I32: |
113 | Def->setDesc(TII.get(GE_U_I32)); |
114 | Inverted = true; |
115 | break; |
116 | case LE_U_I32: |
117 | Def->setDesc(TII.get(GT_U_I32)); |
118 | Inverted = true; |
119 | break; |
120 | case EQ_I64: |
121 | Def->setDesc(TII.get(NE_I64)); |
122 | Inverted = true; |
123 | break; |
124 | case NE_I64: |
125 | Def->setDesc(TII.get(EQ_I64)); |
126 | Inverted = true; |
127 | break; |
128 | case GT_S_I64: |
129 | Def->setDesc(TII.get(LE_S_I64)); |
130 | Inverted = true; |
131 | break; |
132 | case GE_S_I64: |
133 | Def->setDesc(TII.get(LT_S_I64)); |
134 | Inverted = true; |
135 | break; |
136 | case LT_S_I64: |
137 | Def->setDesc(TII.get(GE_S_I64)); |
138 | Inverted = true; |
139 | break; |
140 | case LE_S_I64: |
141 | Def->setDesc(TII.get(GT_S_I64)); |
142 | Inverted = true; |
143 | break; |
144 | case GT_U_I64: |
145 | Def->setDesc(TII.get(LE_U_I64)); |
146 | Inverted = true; |
147 | break; |
148 | case GE_U_I64: |
149 | Def->setDesc(TII.get(LT_U_I64)); |
150 | Inverted = true; |
151 | break; |
152 | case LT_U_I64: |
153 | Def->setDesc(TII.get(GE_U_I64)); |
154 | Inverted = true; |
155 | break; |
156 | case LE_U_I64: |
157 | Def->setDesc(TII.get(GT_U_I64)); |
158 | Inverted = true; |
159 | break; |
160 | case EQ_F32: |
161 | Def->setDesc(TII.get(NE_F32)); |
162 | Inverted = true; |
163 | break; |
164 | case NE_F32: |
165 | Def->setDesc(TII.get(EQ_F32)); |
166 | Inverted = true; |
167 | break; |
168 | case EQ_F64: |
169 | Def->setDesc(TII.get(NE_F64)); |
170 | Inverted = true; |
171 | break; |
172 | case NE_F64: |
173 | Def->setDesc(TII.get(EQ_F64)); |
174 | Inverted = true; |
175 | break; |
176 | case EQZ_I32: { |
177 | // Invert an eqz by replacing it with its operand. |
178 | Cond = Def->getOperand(1).getReg(); |
179 | Def->eraseFromParent(); |
180 | Inverted = true; |
181 | break; |
182 | } |
183 | default: |
184 | break; |
185 | } |
186 | } |
187 | |
188 | // If we weren't able to invert the condition in place. Insert an |
189 | // instruction to invert it. |
190 | if (!Inverted) { |
191 | Register Tmp = MRI.createVirtualRegister(&WebAssembly::I32RegClass); |
192 | BuildMI(MBB, MI, MI->getDebugLoc(), TII.get(WebAssembly::EQZ_I32), Tmp) |
193 | .addReg(Cond); |
194 | MFI.stackifyVReg(MRI, Tmp); |
195 | Cond = Tmp; |
196 | Inverted = true; |
Value stored to 'Inverted' is never read | |
197 | } |
198 | |
199 | // The br_unless condition has now been inverted. Insert a br_if and |
200 | // delete the br_unless. |
201 | assert(Inverted)(static_cast<void> (0)); |
202 | BuildMI(MBB, MI, MI->getDebugLoc(), TII.get(WebAssembly::BR_IF)) |
203 | .add(MI->getOperand(0)) |
204 | .addReg(Cond); |
205 | MBB.erase(MI); |
206 | } |
207 | } |
208 | |
209 | return true; |
210 | } |