LLVM: lib/Target/WebAssembly/WebAssemblyFixBrTableDefaults.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
24
25using namespace llvm;
26
27#define DEBUG_TYPE "wasm-fix-br-table-defaults"
28
29namespace {
30
32 StringRef getPassName() const override {
33 return "WebAssembly Fix br_table Defaults";
34 }
35
37
38public:
39 static char ID;
41};
42
43char WebAssemblyFixBrTableDefaults::ID = 0;
44
45
46
47
48
49
50
53
55 if (!WST.hasAddr64())
56 return;
57
58 assert(MI.getDesc().getOpcode() == WebAssembly::BR_TABLE_I64 &&
59 "64-bit br_table pseudo instruction expected");
60
61
63 if (ExtMI->getOpcode() == WebAssembly::I64_EXTEND_U_I32) {
64
65 auto ExtDefReg = ExtMI->getOperand(0).getReg();
66 assert(MI.getOperand(0).getReg() == ExtDefReg);
67 MI.getOperand(0).setReg(ExtMI->getOperand(1).getReg());
69
70 ExtMI->eraseFromParent();
71 }
72 } else {
73
77 WST.getInstrInfo()->get(WebAssembly::I32_WRAP_I64), Reg32)
78 .addReg(MI.getOperand(0).getReg());
79 MI.getOperand(0).setReg(Reg32);
80 }
81
82
83
84 MI.setDesc(WST.getInstrInfo()->get(WebAssembly::BR_TABLE_I32));
85}
86
87
88
89
90
91
94
95 assert(MBB->pred_size() == 1 && "Expected a single guard predecessor");
96 auto *HeaderMBB = *MBB->pred_begin();
97
98
99
100
104 bool Analyzed = .analyzeBranch(*HeaderMBB, TBB, FBB, Cond);
105 assert(Analyzed && "Could not analyze jump header branches");
106 (void)Analyzed;
107
108
109
110
111
112
113
114
115
117 assert((FBB == nullptr || FBB == MBB) &&
118 "Expected jump or fallthrough to br_table block");
119 assert(Cond.size() == 2 && Cond[1].isReg() && "Unexpected condition info");
120
121
122
123
124
125
126
128 auto *RangeCheck = MRI.getVRegDef(Cond[1].getReg());
129 assert(RangeCheck != nullptr);
130 if (RangeCheck->getOpcode() != WebAssembly::GT_U_I32)
131 return nullptr;
132
133
134 MI.removeOperand(MI.getNumExplicitOperands() - 1);
136 }
137
138
139 TII.removeBranch(*HeaderMBB, nullptr);
140 HeaderMBB->splice(HeaderMBB->end(), MBB, MBB->begin(), MBB->end());
141
142
143
144 HeaderMBB->removeSuccessor(MBB);
145 for (auto &Succ : MBB->successors())
146 if (HeaderMBB->isSuccessor(Succ))
147 HeaderMBB->removeSuccessor(Succ);
148 HeaderMBB->transferSuccessorsAndUpdatePHIs(MBB);
149
150
152
153 return HeaderMBB;
154}
155
156bool WebAssemblyFixBrTableDefaults::runOnMachineFunction(MachineFunction &MF) {
157 LLVM_DEBUG(dbgs() << "********** Fixing br_table Default Targets **********\n"
158 "********** Function: "
159 << MF.getName() << '\n');
160
164 MBBSet;
165 for (auto &MBB : MF)
167
168 while (!MBBSet.empty()) {
173 fixBrTableIndex(MI, MBB, MF);
174 auto *Fixed = fixBrTableDefault(MI, MBB, MF);
175 if (Fixed != nullptr) {
178 }
179 break;
180 }
181 }
182 }
183
185
187 return true;
188 }
189
190 return false;
191}
192
193}
194
196 "Removes range checks and sets br_table default targets", false,
197 false)
198
200 return new WebAssemblyFixBrTableDefaults();
201}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file provides WebAssembly-specific target descriptions.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
void erase(iterator MBBI)
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
A vector that has set insertion semantics.
bool remove(const value_type &X)
Remove an item from the set vector.
bool empty() const
Determine if the SetVector is empty or not.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isBrTable(unsigned Opc)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createWebAssemblyFixBrTableDefaults()
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.