LLVM  9.0.0svn
WebAssemblySetP2AlignOperands.cpp
Go to the documentation of this file.
1 //=- WebAssemblySetP2AlignOperands.cpp - Set alignments on loads and stores -=//
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 sets the p2align operands on load and store instructions.
11 ///
12 //===----------------------------------------------------------------------===//
13 
15 #include "WebAssembly.h"
19 #include "llvm/CodeGen/Passes.h"
20 #include "llvm/Support/Debug.h"
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "wasm-set-p2align-operands"
25 
26 namespace {
27 class WebAssemblySetP2AlignOperands final : public MachineFunctionPass {
28 public:
29  static char ID; // Pass identification, replacement for typeid
30  WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {}
31 
32  StringRef getPassName() const override {
33  return "WebAssembly Set p2align Operands";
34  }
35 
36  void getAnalysisUsage(AnalysisUsage &AU) const override {
37  AU.setPreservesCFG();
41  }
42 
43  bool runOnMachineFunction(MachineFunction &MF) override;
44 };
45 } // end anonymous namespace
46 
48 INITIALIZE_PASS(WebAssemblySetP2AlignOperands, DEBUG_TYPE,
49  "Set the p2align operands for WebAssembly loads and stores",
50  false, false)
51 
53  return new WebAssemblySetP2AlignOperands();
54 }
55 
56 static void rewriteP2Align(MachineInstr &MI, unsigned OperandNo) {
57  assert(MI.getOperand(OperandNo).getImm() == 0 &&
58  "ISel should set p2align operands to 0");
59  assert(MI.hasOneMemOperand() &&
60  "Load and store instructions have exactly one mem operand");
61  assert((*MI.memoperands_begin())->getSize() ==
62  (UINT64_C(1) << WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
63  "Default p2align value should be natural");
64  assert(MI.getDesc().OpInfo[OperandNo].OperandType ==
66  "Load and store instructions should have a p2align operand");
67  uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
68 
69  // WebAssembly does not currently support supernatural alignment.
70  P2Align = std::min(P2Align,
72 
73  MI.getOperand(OperandNo).setImm(P2Align);
74 }
75 
76 bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
77  LLVM_DEBUG({
78  dbgs() << "********** Set p2align Operands **********\n"
79  << "********** Function: " << MF.getName() << '\n';
80  });
81 
82  bool Changed = false;
83 
84  for (auto &MBB : MF) {
85  for (auto &MI : MBB) {
86  switch (MI.getOpcode()) {
87  case WebAssembly::LOAD_I32:
88  case WebAssembly::LOAD_I64:
89  case WebAssembly::LOAD_F32:
90  case WebAssembly::LOAD_F64:
91  case WebAssembly::LOAD_v16i8:
92  case WebAssembly::LOAD_v8i16:
93  case WebAssembly::LOAD_v4i32:
94  case WebAssembly::LOAD_v2i64:
95  case WebAssembly::LOAD_v4f32:
96  case WebAssembly::LOAD_v2f64:
97  case WebAssembly::LOAD8_S_I32:
98  case WebAssembly::LOAD8_U_I32:
99  case WebAssembly::LOAD16_S_I32:
100  case WebAssembly::LOAD16_U_I32:
101  case WebAssembly::LOAD8_S_I64:
102  case WebAssembly::LOAD8_U_I64:
103  case WebAssembly::LOAD16_S_I64:
104  case WebAssembly::LOAD16_U_I64:
105  case WebAssembly::LOAD32_S_I64:
106  case WebAssembly::LOAD32_U_I64:
107  case WebAssembly::ATOMIC_LOAD_I32:
108  case WebAssembly::ATOMIC_LOAD8_U_I32:
109  case WebAssembly::ATOMIC_LOAD16_U_I32:
110  case WebAssembly::ATOMIC_LOAD_I64:
111  case WebAssembly::ATOMIC_LOAD8_U_I64:
112  case WebAssembly::ATOMIC_LOAD16_U_I64:
113  case WebAssembly::ATOMIC_LOAD32_U_I64:
114  case WebAssembly::ATOMIC_RMW8_U_ADD_I32:
115  case WebAssembly::ATOMIC_RMW8_U_ADD_I64:
116  case WebAssembly::ATOMIC_RMW8_U_SUB_I32:
117  case WebAssembly::ATOMIC_RMW8_U_SUB_I64:
118  case WebAssembly::ATOMIC_RMW8_U_AND_I32:
119  case WebAssembly::ATOMIC_RMW8_U_AND_I64:
120  case WebAssembly::ATOMIC_RMW8_U_OR_I32:
121  case WebAssembly::ATOMIC_RMW8_U_OR_I64:
122  case WebAssembly::ATOMIC_RMW8_U_XOR_I32:
123  case WebAssembly::ATOMIC_RMW8_U_XOR_I64:
124  case WebAssembly::ATOMIC_RMW8_U_XCHG_I32:
125  case WebAssembly::ATOMIC_RMW8_U_XCHG_I64:
126  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32:
127  case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64:
128  case WebAssembly::ATOMIC_RMW16_U_ADD_I32:
129  case WebAssembly::ATOMIC_RMW16_U_ADD_I64:
130  case WebAssembly::ATOMIC_RMW16_U_SUB_I32:
131  case WebAssembly::ATOMIC_RMW16_U_SUB_I64:
132  case WebAssembly::ATOMIC_RMW16_U_AND_I32:
133  case WebAssembly::ATOMIC_RMW16_U_AND_I64:
134  case WebAssembly::ATOMIC_RMW16_U_OR_I32:
135  case WebAssembly::ATOMIC_RMW16_U_OR_I64:
136  case WebAssembly::ATOMIC_RMW16_U_XOR_I32:
137  case WebAssembly::ATOMIC_RMW16_U_XOR_I64:
138  case WebAssembly::ATOMIC_RMW16_U_XCHG_I32:
139  case WebAssembly::ATOMIC_RMW16_U_XCHG_I64:
140  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32:
141  case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64:
142  case WebAssembly::ATOMIC_RMW_ADD_I32:
143  case WebAssembly::ATOMIC_RMW32_U_ADD_I64:
144  case WebAssembly::ATOMIC_RMW_SUB_I32:
145  case WebAssembly::ATOMIC_RMW32_U_SUB_I64:
146  case WebAssembly::ATOMIC_RMW_AND_I32:
147  case WebAssembly::ATOMIC_RMW32_U_AND_I64:
148  case WebAssembly::ATOMIC_RMW_OR_I32:
149  case WebAssembly::ATOMIC_RMW32_U_OR_I64:
150  case WebAssembly::ATOMIC_RMW_XOR_I32:
151  case WebAssembly::ATOMIC_RMW32_U_XOR_I64:
152  case WebAssembly::ATOMIC_RMW_XCHG_I32:
153  case WebAssembly::ATOMIC_RMW32_U_XCHG_I64:
154  case WebAssembly::ATOMIC_RMW_CMPXCHG_I32:
155  case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64:
156  case WebAssembly::ATOMIC_RMW_ADD_I64:
157  case WebAssembly::ATOMIC_RMW_SUB_I64:
158  case WebAssembly::ATOMIC_RMW_AND_I64:
159  case WebAssembly::ATOMIC_RMW_OR_I64:
160  case WebAssembly::ATOMIC_RMW_XOR_I64:
161  case WebAssembly::ATOMIC_RMW_XCHG_I64:
162  case WebAssembly::ATOMIC_RMW_CMPXCHG_I64:
163  case WebAssembly::ATOMIC_NOTIFY:
164  case WebAssembly::ATOMIC_WAIT_I32:
165  case WebAssembly::ATOMIC_WAIT_I64:
167  break;
168  case WebAssembly::STORE_I32:
169  case WebAssembly::STORE_I64:
170  case WebAssembly::STORE_F32:
171  case WebAssembly::STORE_F64:
172  case WebAssembly::STORE_v16i8:
173  case WebAssembly::STORE_v8i16:
174  case WebAssembly::STORE_v4i32:
175  case WebAssembly::STORE_v2i64:
176  case WebAssembly::STORE_v4f32:
177  case WebAssembly::STORE_v2f64:
178  case WebAssembly::STORE8_I32:
179  case WebAssembly::STORE16_I32:
180  case WebAssembly::STORE8_I64:
181  case WebAssembly::STORE16_I64:
182  case WebAssembly::STORE32_I64:
183  case WebAssembly::ATOMIC_STORE_I32:
184  case WebAssembly::ATOMIC_STORE8_I32:
185  case WebAssembly::ATOMIC_STORE16_I32:
186  case WebAssembly::ATOMIC_STORE_I64:
187  case WebAssembly::ATOMIC_STORE8_I64:
188  case WebAssembly::ATOMIC_STORE16_I64:
189  case WebAssembly::ATOMIC_STORE32_I64:
191  break;
192  default:
193  break;
194  }
195  }
196  }
197 
198  return Changed;
199 }
static const unsigned LoadP2AlignOperandNo
The operand number of the load or store p2align in load/store instructions.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
static uint32_t getAlignment(const MCSectionCOFF &Sec)
static const unsigned StoreP2AlignOperandNo
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:78
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:405
AnalysisUsage & addPreservedID(const void *ID)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
This file provides WebAssembly-specific target descriptions.
Represent the analysis usage information of a pass.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:548
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
FunctionPass * createWebAssemblySetP2AlignOperands()
unsigned GetDefaultP2Align(unsigned Opcode)
Return the default p2align value for a load or store with the given opcode.
INITIALIZE_PASS(WebAssemblySetP2AlignOperands, DEBUG_TYPE, "Set the p2align operands for WebAssembly loads and stores", false, false) FunctionPass *llvm
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:533
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:285
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Representation of each machine instruction.
Definition: MachineInstr.h:63
p2align immediate for load and store address alignment.
This file declares WebAssembly-specific per-machine-function information.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static void rewriteP2Align(MachineInstr &MI, unsigned OperandNo)
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:544