Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/LowerAtomicPass.cpp
35269 views
1
//===- LowerAtomic.cpp - Lower atomic intrinsics --------------------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This pass lowers atomic intrinsics to non-atomic form for use in a known
10
// non-preemptible environment.
11
//
12
//===----------------------------------------------------------------------===//
13
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"
21
using namespace llvm;
22
23
#define DEBUG_TYPE "lower-atomic"
24
25
static bool LowerFenceInst(FenceInst *FI) {
26
FI->eraseFromParent();
27
return true;
28
}
29
30
static bool LowerLoadInst(LoadInst *LI) {
31
LI->setAtomic(AtomicOrdering::NotAtomic);
32
return true;
33
}
34
35
static bool LowerStoreInst(StoreInst *SI) {
36
SI->setAtomic(AtomicOrdering::NotAtomic);
37
return true;
38
}
39
40
static bool runOnBasicBlock(BasicBlock &BB) {
41
bool Changed = false;
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)) {
50
if (LI->isAtomic())
51
LowerLoadInst(LI);
52
} else if (StoreInst *SI = dyn_cast<StoreInst>(&Inst)) {
53
if (SI->isAtomic())
54
LowerStoreInst(SI);
55
}
56
}
57
return Changed;
58
}
59
60
static bool lowerAtomics(Function &F) {
61
bool Changed = false;
62
for (BasicBlock &BB : F) {
63
Changed |= runOnBasicBlock(BB);
64
}
65
return Changed;
66
}
67
68
PreservedAnalyses LowerAtomicPass::run(Function &F, FunctionAnalysisManager &) {
69
if (lowerAtomics(F))
70
return PreservedAnalyses::none();
71
return PreservedAnalyses::all();
72
}
73
74
namespace {
75
class LowerAtomicLegacyPass : public FunctionPass {
76
public:
77
static char ID;
78
79
LowerAtomicLegacyPass() : FunctionPass(ID) {
80
initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry());
81
}
82
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();
88
}
89
90
private:
91
LowerAtomicPass Impl;
92
};
93
}
94
95
char LowerAtomicLegacyPass::ID = 0;
96
INITIALIZE_PASS(LowerAtomicLegacyPass, "loweratomic",
97
"Lower atomic intrinsics to non-atomic form", false, false)
98
99
Pass *llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); }
100
101