1fe6060f1SDimitry Andric //===-- NVPTXAtomicLower.cpp - Lower atomics of local memory ----*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // Lower atomics of local memory to simple load/stores 10fe6060f1SDimitry Andric // 11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include "NVPTXAtomicLower.h" 14fe6060f1SDimitry Andric #include "llvm/CodeGen/StackProtector.h" 15fe6060f1SDimitry Andric #include "llvm/IR/Constants.h" 16fe6060f1SDimitry Andric #include "llvm/IR/Function.h" 17fe6060f1SDimitry Andric #include "llvm/IR/IRBuilder.h" 18fe6060f1SDimitry Andric #include "llvm/IR/InstIterator.h" 19fe6060f1SDimitry Andric #include "llvm/IR/Instructions.h" 20*81ad6265SDimitry Andric #include "llvm/Transforms/Utils/LowerAtomic.h" 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric #include "MCTargetDesc/NVPTXBaseInfo.h" 23fe6060f1SDimitry Andric using namespace llvm; 24fe6060f1SDimitry Andric 25fe6060f1SDimitry Andric namespace { 26fe6060f1SDimitry Andric // Hoisting the alloca instructions in the non-entry blocks to the entry 27fe6060f1SDimitry Andric // block. 28fe6060f1SDimitry Andric class NVPTXAtomicLower : public FunctionPass { 29fe6060f1SDimitry Andric public: 30fe6060f1SDimitry Andric static char ID; // Pass ID NVPTXAtomicLower()31fe6060f1SDimitry Andric NVPTXAtomicLower() : FunctionPass(ID) {} 32fe6060f1SDimitry Andric getAnalysisUsage(AnalysisUsage & AU) const33fe6060f1SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 34fe6060f1SDimitry Andric AU.setPreservesCFG(); 35fe6060f1SDimitry Andric } 36fe6060f1SDimitry Andric getPassName() const37fe6060f1SDimitry Andric StringRef getPassName() const override { 38fe6060f1SDimitry Andric return "NVPTX lower atomics of local memory"; 39fe6060f1SDimitry Andric } 40fe6060f1SDimitry Andric 41fe6060f1SDimitry Andric bool runOnFunction(Function &F) override; 42fe6060f1SDimitry Andric }; 43fe6060f1SDimitry Andric } // namespace 44fe6060f1SDimitry Andric runOnFunction(Function & F)45fe6060f1SDimitry Andricbool NVPTXAtomicLower::runOnFunction(Function &F) { 46fe6060f1SDimitry Andric SmallVector<AtomicRMWInst *> LocalMemoryAtomics; 47fe6060f1SDimitry Andric for (Instruction &I : instructions(F)) 48fe6060f1SDimitry Andric if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) 49fe6060f1SDimitry Andric if (RMWI->getPointerAddressSpace() == ADDRESS_SPACE_LOCAL) 50fe6060f1SDimitry Andric LocalMemoryAtomics.push_back(RMWI); 51fe6060f1SDimitry Andric 52fe6060f1SDimitry Andric bool Changed = false; 53fe6060f1SDimitry Andric for (AtomicRMWInst *RMWI : LocalMemoryAtomics) 54fe6060f1SDimitry Andric Changed |= lowerAtomicRMWInst(RMWI); 55fe6060f1SDimitry Andric return Changed; 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric char NVPTXAtomicLower::ID = 0; 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric namespace llvm { 61fe6060f1SDimitry Andric void initializeNVPTXAtomicLowerPass(PassRegistry &); 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric INITIALIZE_PASS(NVPTXAtomicLower, "nvptx-atomic-lower", 65fe6060f1SDimitry Andric "Lower atomics of local memory to simple load/stores", false, 66fe6060f1SDimitry Andric false) 67fe6060f1SDimitry Andric createNVPTXAtomicLowerPass()68fe6060f1SDimitry AndricFunctionPass *llvm::createNVPTXAtomicLowerPass() { 69fe6060f1SDimitry Andric return new NVPTXAtomicLower(); 70fe6060f1SDimitry Andric } 71