================
@@ -0,0 +1,97 @@
+//===-- WebAssemblyFixupAtomics.cpp - Fixup Atomics 
-----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Fixes memory ordering operands for atomic instructions.
+///
+/// This is used because ISel selects atomics with a default value for the
+/// memory ordering immediate operand. Even though we run this pass early in
+/// the MI pass pipeline, MI passes should still use getMergedOrdering() on
+/// the MachineMemOperand to get the ordering rther than the immediate.
+///
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
+#include "WebAssembly.h"
+#include "WebAssemblySubtarget.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "wasm-fixup-atomics"
+
+namespace {
+class WebAssemblyFixupAtomics final : public MachineFunctionPass {
+  StringRef getPassName() const override { return "WebAssembly Fixup Atomics"; 
}
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesCFG();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+  WebAssemblyFixupAtomics() : MachineFunctionPass(ID) {}
+};
+} // end anonymous namespace
+
+char WebAssemblyFixupAtomics::ID = 0;
+INITIALIZE_PASS(WebAssemblyFixupAtomics, DEBUG_TYPE,
+                "Fixup the memory ordering of atomics", false, false)
+
+FunctionPass *llvm::createWebAssemblyFixupAtomics() {
+  return new WebAssemblyFixupAtomics();
+}
+
+bool WebAssemblyFixupAtomics::runOnMachineFunction(MachineFunction &MF) {
+  LLVM_DEBUG(dbgs() << "********** Fixup Atomics **********\n"
+                    << "********** Function: " << MF.getName() << '\n');
+
+  bool Changed = false;
+  if (!MF.getSubtarget<WebAssemblySubtarget>().hasRelaxedAtomics())
+    return Changed;
+
+  for (auto &MBB : MF) {
+    for (auto &MI : MBB) {
+      const MCInstrDesc &Desc = MI.getDesc();
+      for (unsigned I = 0, E = MI.getNumExplicitOperands(); I < E; ++I) {
+        if (I < Desc.getNumOperands() &&
+            Desc.operands()[I].OperandType == WebAssembly::OPERAND_MEMORDER &&
+            // Fences are already selected with the correct ordering.
+            MI.getOpcode() != WebAssembly::ATOMIC_FENCE) {
+          assert(MI.getOperand(I).getImm() == wasm::WASM_MEM_ORDER_SEQ_CST &&
+                 "Expected seqcst default atomics from ISel");
+          assert(!MI.memoperands_empty());
+          unsigned Order = wasm::WASM_MEM_ORDER_SEQ_CST;
+          auto *MMO = *MI.memoperands_begin();
+          switch (MMO->getMergedOrdering()) {
+          case AtomicOrdering::Acquire:
+          case AtomicOrdering::Release:
+          case AtomicOrdering::AcquireRelease:
+          case AtomicOrdering::Monotonic:
+            Order = wasm::WASM_MEM_ORDER_ACQ_REL;
+            break;
+          default:
+            Order = wasm::WASM_MEM_ORDER_SEQ_CST;
+            break;
+          }
+          if (MI.getOperand(I).getImm() != Order) {
+            MI.getOperand(I).setImm(Order);
----------------
arsenm wrote:

This is pretty hacky. It would be much better to directly select to the correct 
value in the first place 

https://github.com/llvm/llvm-project/pull/184900
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to