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