Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/LowerAtomicPass.cpp
35269 views
//===- LowerAtomic.cpp - Lower atomic intrinsics --------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This pass lowers atomic intrinsics to non-atomic form for use in a known9// non-preemptible environment.10//11//===----------------------------------------------------------------------===//1213#include "llvm/Transforms/Scalar/LowerAtomicPass.h"14#include "llvm/IR/Function.h"15#include "llvm/IR/IRBuilder.h"16#include "llvm/InitializePasses.h"17#include "llvm/Pass.h"18#include "llvm/Transforms/Scalar.h"19#include "llvm/Transforms/Utils/LowerAtomic.h"20using namespace llvm;2122#define DEBUG_TYPE "lower-atomic"2324static bool LowerFenceInst(FenceInst *FI) {25FI->eraseFromParent();26return true;27}2829static bool LowerLoadInst(LoadInst *LI) {30LI->setAtomic(AtomicOrdering::NotAtomic);31return true;32}3334static bool LowerStoreInst(StoreInst *SI) {35SI->setAtomic(AtomicOrdering::NotAtomic);36return true;37}3839static bool runOnBasicBlock(BasicBlock &BB) {40bool Changed = false;41for (Instruction &Inst : make_early_inc_range(BB)) {42if (FenceInst *FI = dyn_cast<FenceInst>(&Inst))43Changed |= LowerFenceInst(FI);44else if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&Inst))45Changed |= lowerAtomicCmpXchgInst(CXI);46else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&Inst))47Changed |= lowerAtomicRMWInst(RMWI);48else if (LoadInst *LI = dyn_cast<LoadInst>(&Inst)) {49if (LI->isAtomic())50LowerLoadInst(LI);51} else if (StoreInst *SI = dyn_cast<StoreInst>(&Inst)) {52if (SI->isAtomic())53LowerStoreInst(SI);54}55}56return Changed;57}5859static bool lowerAtomics(Function &F) {60bool Changed = false;61for (BasicBlock &BB : F) {62Changed |= runOnBasicBlock(BB);63}64return Changed;65}6667PreservedAnalyses LowerAtomicPass::run(Function &F, FunctionAnalysisManager &) {68if (lowerAtomics(F))69return PreservedAnalyses::none();70return PreservedAnalyses::all();71}7273namespace {74class LowerAtomicLegacyPass : public FunctionPass {75public:76static char ID;7778LowerAtomicLegacyPass() : FunctionPass(ID) {79initializeLowerAtomicLegacyPassPass(*PassRegistry::getPassRegistry());80}8182bool runOnFunction(Function &F) override {83// Don't skip optnone functions; atomics still need to be lowered.84FunctionAnalysisManager DummyFAM;85auto PA = Impl.run(F, DummyFAM);86return !PA.areAllPreserved();87}8889private:90LowerAtomicPass Impl;91};92}9394char LowerAtomicLegacyPass::ID = 0;95INITIALIZE_PASS(LowerAtomicLegacyPass, "loweratomic",96"Lower atomic intrinsics to non-atomic form", false, false)9798Pass *llvm::createLowerAtomicPass() { return new LowerAtomicLegacyPass(); }99100101