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/IR/IRBuilder.h"
17 #include "llvm/InitializePasses.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Transforms/Scalar.h"
20 #include "llvm/Transforms/Utils/LowerAtomic.h"
23 #define DEBUG_TYPE "loweratomic"
25 static bool LowerFenceInst(FenceInst
*FI
) {
26 FI
->eraseFromParent();
30 static bool LowerLoadInst(LoadInst
*LI
) {
31 LI
->setAtomic(AtomicOrdering::NotAtomic
);
35 static bool LowerStoreInst(StoreInst
*SI
) {
36 SI
->setAtomic(AtomicOrdering::NotAtomic
);
40 static bool runOnBasicBlock(BasicBlock
&BB
) {
42 for (Instruction
&Inst
: make_early_inc_range(BB
)) {
43 if (FenceInst
*FI
= dyn_cast
<FenceInst
>(&Inst
))
44 Changed
|= LowerFenceInst(FI
);
45 else if (AtomicCmpXchgInst
*CXI
= dyn_cast
<AtomicCmpXchgInst
>(&Inst
))
46 Changed
|= lowerAtomicCmpXchgInst(CXI
);
47 else if (AtomicRMWInst
*RMWI
= dyn_cast
<AtomicRMWInst
>(&Inst
))
48 Changed
|= lowerAtomicRMWInst(RMWI
);
49 else if (LoadInst
*LI
= dyn_cast
<LoadInst
>(&Inst
)) {
52 } else if (StoreInst
*SI
= dyn_cast
<StoreInst
>(&Inst
)) {
60 static bool lowerAtomics(Function
&F
) {
62 for (BasicBlock
&BB
: F
) {
63 Changed
|= runOnBasicBlock(BB
);
68 PreservedAnalyses
LowerAtomicPass::run(Function
&F
, FunctionAnalysisManager
&) {
70 return PreservedAnalyses::none();
71 return PreservedAnalyses::all();
75 class LowerAtomicLegacyPass
: public FunctionPass
{
79 LowerAtomicLegacyPass() : FunctionPass(ID
) {
80 initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry());
83 bool runOnFunction(Function
&F
) override
{
84 // Don't skip optnone functions; atomics still need to be lowered.
85 FunctionAnalysisManager DummyFAM
;
86 auto PA
= Impl
.run(F
, DummyFAM
);
87 return !PA
.areAllPreserved();
95 char LowerAtomicLegacyPass::ID
= 0;
96 INITIALIZE_PASS(LowerAtomicLegacyPass
, "loweratomic",
97 "Lower atomic intrinsics to non-atomic form", false, false)
99 Pass
*llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); }