diff --git a/llvm/include/llvm/Transforms/Scalar/LowerAtomicPass.h b/llvm/include/llvm/Transforms/Scalar/LowerAtomicPass.h new file mode 100644 index 0000000000000000000000000000000000000000..60bbf916fced4b08de122165a72ef5e9402e7e63 --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/LowerAtomicPass.h @@ -0,0 +1,30 @@ +//===- LowerAtomicPass.h - Lower atomic intrinsics --------------*- C++ -*-===// +// +// 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 +// This pass lowers atomic intrinsics to non-atomic form for use in a known +// non-preemptible environment. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_LOWERATOMICPASS_H +#define LLVM_TRANSFORMS_SCALAR_LOWERATOMICPASS_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// A pass that lowers atomic intrinsic into non-atomic intrinsics. +class LowerAtomicPass : public PassInfoMixin<LowerAtomicPass> { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &); + static bool isRequired() { return true; } +}; + +} + +#endif // LLVM_TRANSFORMS_SCALAR_LOWERATOMICPASS_H diff --git a/llvm/include/llvm/Transforms/Scalar/LowerAtomic.h b/llvm/include/llvm/Transforms/Utils/LowerAtomic.h similarity index 71% rename from llvm/include/llvm/Transforms/Scalar/LowerAtomic.h rename to llvm/include/llvm/Transforms/Utils/LowerAtomic.h index 87d945d06901b71b1a8d72cba0f27e854eb1532f..cd16d77d50f93327aba3f004e323ca858d989a81 100644 --- a/llvm/include/llvm/Transforms/Scalar/LowerAtomic.h +++ b/llvm/include/llvm/Transforms/Utils/LowerAtomic.h @@ -1,4 +1,4 @@ -//===- LowerAtomic.cpp - Lower atomic intrinsics ----------------*- C++ -*-===// +//===- LowerAtomic.h - Lower atomic intrinsics ------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,18 +14,13 @@ #ifndef LLVM_TRANSFORMS_SCALAR_LOWERATOMIC_H #define LLVM_TRANSFORMS_SCALAR_LOWERATOMIC_H -#include "llvm/IR/PassManager.h" - namespace llvm { +class AtomicCmpXchgInst; +class AtomicRMWInst; -/// A pass that lowers atomic intrinsic into non-atomic intrinsics. -class LowerAtomicPass : public PassInfoMixin<LowerAtomicPass> { -public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &); - static bool isRequired() { return true; } -}; +/// Convert the given Cmpxchg into primitive load and compare. +bool lowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI); -class AtomicRMWInst; /// Convert the given RMWI into primitive load and stores, /// assuming that doing so is legal. Return true if the lowering /// succeeds. diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 1f407a6fcfca6b78828a8fad1e5b44aa0eb3f2d2..8de919d242913ccd74c5d1f31cb4c208930d2c27 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -185,7 +185,7 @@ #include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h" #include "llvm/Transforms/Scalar/LoopUnrollPass.h" #include "llvm/Transforms/Scalar/LoopVersioningLICM.h" -#include "llvm/Transforms/Scalar/LowerAtomic.h" +#include "llvm/Transforms/Scalar/LowerAtomicPass.h" #include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h" diff --git a/llvm/lib/Target/NVPTX/NVPTXAtomicLower.cpp b/llvm/lib/Target/NVPTX/NVPTXAtomicLower.cpp index 10bf56fd9a9161f2707f3ed191877a16afc1efd7..9661dffd3dae269e263ea45fe2cbeac525f32f59 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAtomicLower.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAtomicLower.cpp @@ -17,7 +17,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" -#include "llvm/Transforms/Scalar/LowerAtomic.h" +#include "llvm/Transforms/Utils/LowerAtomic.h" #include "MCTargetDesc/NVPTXBaseInfo.h" using namespace llvm; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 6d66ce44fb21e9e6bef480897b88e9535aa1723c..30db4beff6f661d40c657c0187472a1652c2c470 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -30,7 +30,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Scalar/LowerAtomic.h" +#include "llvm/Transforms/Scalar/LowerAtomicPass.h" #include "llvm/Transforms/Utils.h" using namespace llvm; diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt index 2b90abb97a52cb58657904cc35a0f5751f0d4d86..0cd474bcc1e0cdacb202a3f0e0563e425716b7f4 100644 --- a/llvm/lib/Transforms/Scalar/CMakeLists.txt +++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt @@ -47,7 +47,7 @@ add_llvm_component_library(LLVMScalarOpts LoopUnrollAndJamPass.cpp LoopUnswitch.cpp LoopVersioningLICM.cpp - LowerAtomic.cpp + LowerAtomicPass.cpp LowerConstantIntrinsics.cpp LowerExpectIntrinsic.cpp LowerGuardIntrinsic.cpp diff --git a/llvm/lib/Transforms/Scalar/LowerAtomicPass.cpp b/llvm/lib/Transforms/Scalar/LowerAtomicPass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6aba913005d0598545fd65894a6ef0a360ef0de7 --- /dev/null +++ b/llvm/lib/Transforms/Scalar/LowerAtomicPass.cpp @@ -0,0 +1,99 @@ +//===- LowerAtomic.cpp - Lower atomic intrinsics --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This pass lowers atomic intrinsics to non-atomic form for use in a known +// non-preemptible environment. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar/LowerAtomicPass.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/LowerAtomic.h" +using namespace llvm; + +#define DEBUG_TYPE "loweratomic" + +static bool LowerFenceInst(FenceInst *FI) { + FI->eraseFromParent(); + return true; +} + +static bool LowerLoadInst(LoadInst *LI) { + LI->setAtomic(AtomicOrdering::NotAtomic); + return true; +} + +static bool LowerStoreInst(StoreInst *SI) { + SI->setAtomic(AtomicOrdering::NotAtomic); + return true; +} + +static bool runOnBasicBlock(BasicBlock &BB) { + bool Changed = false; + for (Instruction &Inst : make_early_inc_range(BB)) { + if (FenceInst *FI = dyn_cast<FenceInst>(&Inst)) + Changed |= LowerFenceInst(FI); + else if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&Inst)) + Changed |= lowerAtomicCmpXchgInst(CXI); + else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&Inst)) + Changed |= lowerAtomicRMWInst(RMWI); + else if (LoadInst *LI = dyn_cast<LoadInst>(&Inst)) { + if (LI->isAtomic()) + LowerLoadInst(LI); + } else if (StoreInst *SI = dyn_cast<StoreInst>(&Inst)) { + if (SI->isAtomic()) + LowerStoreInst(SI); + } + } + return Changed; +} + +static bool lowerAtomics(Function &F) { + bool Changed = false; + for (BasicBlock &BB : F) { + Changed |= runOnBasicBlock(BB); + } + return Changed; +} + +PreservedAnalyses LowerAtomicPass::run(Function &F, FunctionAnalysisManager &) { + if (lowerAtomics(F)) + return PreservedAnalyses::none(); + return PreservedAnalyses::all(); +} + +namespace { +class LowerAtomicLegacyPass : public FunctionPass { +public: + static char ID; + + LowerAtomicLegacyPass() : FunctionPass(ID) { + initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override { + // Don't skip optnone functions; atomics still need to be lowered. + FunctionAnalysisManager DummyFAM; + auto PA = Impl.run(F, DummyFAM); + return !PA.areAllPreserved(); + } + +private: + LowerAtomicPass Impl; + }; +} + +char LowerAtomicLegacyPass::ID = 0; +INITIALIZE_PASS(LowerAtomicLegacyPass, "loweratomic", + "Lower atomic intrinsics to non-atomic form", false, false) + +Pass *llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); } diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt index 58eddb7dcbb8d0d53c58c8b885b86818dbff19c9..c83969f7b12d517d09a977a8ba0e0ac867c02819 100644 --- a/llvm/lib/Transforms/Utils/CMakeLists.txt +++ b/llvm/lib/Transforms/Utils/CMakeLists.txt @@ -44,6 +44,7 @@ add_llvm_component_library(LLVMTransformUtils LoopUnrollRuntime.cpp LoopUtils.cpp LoopVersioning.cpp + LowerAtomic.cpp LowerGlobalDtors.cpp LowerInvoke.cpp LowerMemIntrinsics.cpp diff --git a/llvm/lib/Transforms/Scalar/LowerAtomic.cpp b/llvm/lib/Transforms/Utils/LowerAtomic.cpp similarity index 58% rename from llvm/lib/Transforms/Scalar/LowerAtomic.cpp rename to llvm/lib/Transforms/Utils/LowerAtomic.cpp index 4063e4fe04726a36ee6441ca4b34b2983b66135d..714edddf5c246535c736d42cb4f951361d0374d6 100644 --- a/llvm/lib/Transforms/Scalar/LowerAtomic.cpp +++ b/llvm/lib/Transforms/Utils/LowerAtomic.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar/LowerAtomic.h" +#include "llvm/Transforms/Utils/LowerAtomic.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/InitializePasses.h" @@ -21,7 +21,7 @@ using namespace llvm; #define DEBUG_TYPE "loweratomic" -static bool LowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI) { +bool llvm::lowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI) { IRBuilder<> Builder(CXI); Value *Ptr = CXI->getPointerOperand(); Value *Cmp = CXI->getCompareOperand(); @@ -99,79 +99,3 @@ bool llvm::lowerAtomicRMWInst(AtomicRMWInst *RMWI) { RMWI->eraseFromParent(); return true; } - -static bool LowerFenceInst(FenceInst *FI) { - FI->eraseFromParent(); - return true; -} - -static bool LowerLoadInst(LoadInst *LI) { - LI->setAtomic(AtomicOrdering::NotAtomic); - return true; -} - -static bool LowerStoreInst(StoreInst *SI) { - SI->setAtomic(AtomicOrdering::NotAtomic); - return true; -} - -static bool runOnBasicBlock(BasicBlock &BB) { - bool Changed = false; - for (Instruction &Inst : make_early_inc_range(BB)) { - if (FenceInst *FI = dyn_cast<FenceInst>(&Inst)) - Changed |= LowerFenceInst(FI); - else if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&Inst)) - Changed |= LowerAtomicCmpXchgInst(CXI); - else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&Inst)) - Changed |= lowerAtomicRMWInst(RMWI); - else if (LoadInst *LI = dyn_cast<LoadInst>(&Inst)) { - if (LI->isAtomic()) - LowerLoadInst(LI); - } else if (StoreInst *SI = dyn_cast<StoreInst>(&Inst)) { - if (SI->isAtomic()) - LowerStoreInst(SI); - } - } - return Changed; -} - -static bool lowerAtomics(Function &F) { - bool Changed = false; - for (BasicBlock &BB : F) { - Changed |= runOnBasicBlock(BB); - } - return Changed; -} - -PreservedAnalyses LowerAtomicPass::run(Function &F, FunctionAnalysisManager &) { - if (lowerAtomics(F)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); -} - -namespace { -class LowerAtomicLegacyPass : public FunctionPass { -public: - static char ID; - - LowerAtomicLegacyPass() : FunctionPass(ID) { - initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override { - // Don't skip optnone functions; atomics still need to be lowered. - FunctionAnalysisManager DummyFAM; - auto PA = Impl.run(F, DummyFAM); - return !PA.areAllPreserved(); - } - -private: - LowerAtomicPass Impl; - }; -} - -char LowerAtomicLegacyPass::ID = 0; -INITIALIZE_PASS(LowerAtomicLegacyPass, "loweratomic", - "Lower atomic intrinsics to non-atomic form", false, false) - -Pass *llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); }