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