Line data Source code
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 :
15 : #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16 : #include "WebAssembly.h"
17 : #include "WebAssemblyMachineFunctionInfo.h"
18 : #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
19 : #include "llvm/CodeGen/MachineMemOperand.h"
20 : #include "llvm/CodeGen/Passes.h"
21 : #include "llvm/Support/Debug.h"
22 : #include "llvm/Support/raw_ostream.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 305 : WebAssemblySetP2AlignOperands() : MachineFunctionPass(ID) {}
32 :
33 0 : StringRef getPassName() const override {
34 0 : return "WebAssembly Set p2align Operands";
35 : }
36 :
37 305 : void getAnalysisUsage(AnalysisUsage &AU) const override {
38 305 : AU.setPreservesCFG();
39 : AU.addPreserved<MachineBlockFrequencyInfo>();
40 305 : AU.addPreservedID(MachineDominatorsID);
41 305 : MachineFunctionPass::getAnalysisUsage(AU);
42 305 : }
43 :
44 : bool runOnMachineFunction(MachineFunction &MF) override;
45 : };
46 : } // end anonymous namespace
47 :
48 : char WebAssemblySetP2AlignOperands::ID = 0;
49 199030 : INITIALIZE_PASS(WebAssemblySetP2AlignOperands, DEBUG_TYPE,
50 : "Set the p2align operands for WebAssembly loads and stores",
51 : false, false)
52 :
53 305 : FunctionPass *llvm::createWebAssemblySetP2AlignOperands() {
54 305 : return new WebAssemblySetP2AlignOperands();
55 : }
56 :
57 3557 : 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 ==
66 : WebAssembly::OPERAND_P2ALIGN &&
67 : "Load and store instructions should have a p2align operand");
68 3557 : uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
69 :
70 : // WebAssembly does not currently support supernatural alignment.
71 3557 : P2Align = std::min(P2Align,
72 7114 : uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
73 :
74 7114 : MI.getOperand(OperandNo).setImm(P2Align);
75 3557 : }
76 :
77 2983 : 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 6479 : for (auto &MBB : MF) {
86 28264 : for (auto &MI : MBB) {
87 49536 : switch (MI.getOpcode()) {
88 974 : case WebAssembly::LOAD_I32:
89 : case WebAssembly::LOAD_I64:
90 : case WebAssembly::LOAD_F32:
91 : case WebAssembly::LOAD_F64:
92 : case WebAssembly::LOAD8_S_I32:
93 : case WebAssembly::LOAD8_U_I32:
94 : case WebAssembly::LOAD16_S_I32:
95 : case WebAssembly::LOAD16_U_I32:
96 : case WebAssembly::LOAD8_S_I64:
97 : case WebAssembly::LOAD8_U_I64:
98 : case WebAssembly::LOAD16_S_I64:
99 : case WebAssembly::LOAD16_U_I64:
100 : case WebAssembly::LOAD32_S_I64:
101 : case WebAssembly::LOAD32_U_I64:
102 : case WebAssembly::ATOMIC_LOAD_I32:
103 : case WebAssembly::ATOMIC_LOAD8_U_I32:
104 : case WebAssembly::ATOMIC_LOAD16_U_I32:
105 : case WebAssembly::ATOMIC_LOAD_I64:
106 : case WebAssembly::ATOMIC_LOAD8_U_I64:
107 : case WebAssembly::ATOMIC_LOAD16_U_I64:
108 : case WebAssembly::ATOMIC_LOAD32_U_I64:
109 : case WebAssembly::ATOMIC_RMW8_U_ADD_I32:
110 : case WebAssembly::ATOMIC_RMW8_U_ADD_I64:
111 : case WebAssembly::ATOMIC_RMW8_U_SUB_I32:
112 : case WebAssembly::ATOMIC_RMW8_U_SUB_I64:
113 : case WebAssembly::ATOMIC_RMW8_U_AND_I32:
114 : case WebAssembly::ATOMIC_RMW8_U_AND_I64:
115 : case WebAssembly::ATOMIC_RMW8_U_OR_I32:
116 : case WebAssembly::ATOMIC_RMW8_U_OR_I64:
117 : case WebAssembly::ATOMIC_RMW8_U_XOR_I32:
118 : case WebAssembly::ATOMIC_RMW8_U_XOR_I64:
119 : case WebAssembly::ATOMIC_RMW8_U_XCHG_I32:
120 : case WebAssembly::ATOMIC_RMW8_U_XCHG_I64:
121 : case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I32:
122 : case WebAssembly::ATOMIC_RMW8_U_CMPXCHG_I64:
123 : case WebAssembly::ATOMIC_RMW16_U_ADD_I32:
124 : case WebAssembly::ATOMIC_RMW16_U_ADD_I64:
125 : case WebAssembly::ATOMIC_RMW16_U_SUB_I32:
126 : case WebAssembly::ATOMIC_RMW16_U_SUB_I64:
127 : case WebAssembly::ATOMIC_RMW16_U_AND_I32:
128 : case WebAssembly::ATOMIC_RMW16_U_AND_I64:
129 : case WebAssembly::ATOMIC_RMW16_U_OR_I32:
130 : case WebAssembly::ATOMIC_RMW16_U_OR_I64:
131 : case WebAssembly::ATOMIC_RMW16_U_XOR_I32:
132 : case WebAssembly::ATOMIC_RMW16_U_XOR_I64:
133 : case WebAssembly::ATOMIC_RMW16_U_XCHG_I32:
134 : case WebAssembly::ATOMIC_RMW16_U_XCHG_I64:
135 : case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I32:
136 : case WebAssembly::ATOMIC_RMW16_U_CMPXCHG_I64:
137 : case WebAssembly::ATOMIC_RMW_ADD_I32:
138 : case WebAssembly::ATOMIC_RMW32_U_ADD_I64:
139 : case WebAssembly::ATOMIC_RMW_SUB_I32:
140 : case WebAssembly::ATOMIC_RMW32_U_SUB_I64:
141 : case WebAssembly::ATOMIC_RMW_AND_I32:
142 : case WebAssembly::ATOMIC_RMW32_U_AND_I64:
143 : case WebAssembly::ATOMIC_RMW_OR_I32:
144 : case WebAssembly::ATOMIC_RMW32_U_OR_I64:
145 : case WebAssembly::ATOMIC_RMW_XOR_I32:
146 : case WebAssembly::ATOMIC_RMW32_U_XOR_I64:
147 : case WebAssembly::ATOMIC_RMW_XCHG_I32:
148 : case WebAssembly::ATOMIC_RMW32_U_XCHG_I64:
149 : case WebAssembly::ATOMIC_RMW_CMPXCHG_I32:
150 : case WebAssembly::ATOMIC_RMW32_U_CMPXCHG_I64:
151 : case WebAssembly::ATOMIC_RMW_ADD_I64:
152 : case WebAssembly::ATOMIC_RMW_SUB_I64:
153 : case WebAssembly::ATOMIC_RMW_AND_I64:
154 : case WebAssembly::ATOMIC_RMW_OR_I64:
155 : case WebAssembly::ATOMIC_RMW_XOR_I64:
156 : case WebAssembly::ATOMIC_RMW_XCHG_I64:
157 : case WebAssembly::ATOMIC_RMW_CMPXCHG_I64:
158 : case WebAssembly::ATOMIC_NOTIFY:
159 : case WebAssembly::ATOMIC_WAIT_I32:
160 : case WebAssembly::ATOMIC_WAIT_I64:
161 974 : RewriteP2Align(MI, WebAssembly::LoadP2AlignOperandNo);
162 974 : break;
163 2583 : case WebAssembly::STORE_I32:
164 : case WebAssembly::STORE_I64:
165 : case WebAssembly::STORE_F32:
166 : case WebAssembly::STORE_F64:
167 : case WebAssembly::STORE8_I32:
168 : case WebAssembly::STORE16_I32:
169 : case WebAssembly::STORE8_I64:
170 : case WebAssembly::STORE16_I64:
171 : case WebAssembly::STORE32_I64:
172 : case WebAssembly::ATOMIC_STORE_I32:
173 : case WebAssembly::ATOMIC_STORE8_I32:
174 : case WebAssembly::ATOMIC_STORE16_I32:
175 : case WebAssembly::ATOMIC_STORE_I64:
176 : case WebAssembly::ATOMIC_STORE8_I64:
177 : case WebAssembly::ATOMIC_STORE16_I64:
178 : case WebAssembly::ATOMIC_STORE32_I64:
179 2583 : RewriteP2Align(MI, WebAssembly::StoreP2AlignOperandNo);
180 2583 : break;
181 : default:
182 : break;
183 : }
184 : }
185 : }
186 :
187 2983 : return Changed;
188 : }
|