1 //===- LowerAtomic.cpp - Lower atomic intrinsics --------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This pass lowers atomic intrinsics to non-atomic form for use in a known
10 // non-preemptible environment.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/Scalar/LowerAtomicPass.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/InitializePasses.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Transforms/Scalar.h"
19 #include "llvm/Transforms/Utils/LowerAtomic.h"
22 #define DEBUG_TYPE "lower-atomic"
24 static bool LowerFenceInst(FenceInst
*FI
) {
25 FI
->eraseFromParent();
29 static bool LowerLoadInst(LoadInst
*LI
) {
30 LI
->setAtomic(AtomicOrdering::NotAtomic
);
34 static bool LowerStoreInst(StoreInst
*SI
) {
35 SI
->setAtomic(AtomicOrdering::NotAtomic
);
39 static bool runOnBasicBlock(BasicBlock
&BB
) {
41 for (Instruction
&Inst
: make_early_inc_range(BB
)) {
42 if (FenceInst
*FI
= dyn_cast
<FenceInst
>(&Inst
))
43 Changed
|= LowerFenceInst(FI
);
44 else if (AtomicCmpXchgInst
*CXI
= dyn_cast
<AtomicCmpXchgInst
>(&Inst
))
45 Changed
|= lowerAtomicCmpXchgInst(CXI
);
46 else if (AtomicRMWInst
*RMWI
= dyn_cast
<AtomicRMWInst
>(&Inst
))
47 Changed
|= lowerAtomicRMWInst(RMWI
);
48 else if (LoadInst
*LI
= dyn_cast
<LoadInst
>(&Inst
)) {
51 } else if (StoreInst
*SI
= dyn_cast
<StoreInst
>(&Inst
)) {
59 static bool lowerAtomics(Function
&F
) {
61 for (BasicBlock
&BB
: F
) {
62 Changed
|= runOnBasicBlock(BB
);
67 PreservedAnalyses
LowerAtomicPass::run(Function
&F
, FunctionAnalysisManager
&) {
69 return PreservedAnalyses::none();
70 return PreservedAnalyses::all();
74 class LowerAtomicLegacyPass
: public FunctionPass
{
78 LowerAtomicLegacyPass() : FunctionPass(ID
) {
79 initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry());
82 bool runOnFunction(Function
&F
) override
{
83 // Don't skip optnone functions; atomics still need to be lowered.
84 FunctionAnalysisManager DummyFAM
;
85 auto PA
= Impl
.run(F
, DummyFAM
);
86 return !PA
.areAllPreserved();
94 char LowerAtomicLegacyPass::ID
= 0;
95 INITIALIZE_PASS(LowerAtomicLegacyPass
, "loweratomic",
96 "Lower atomic intrinsics to non-atomic form", false, false)
98 Pass
*llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); }