LLVM  16.0.0git
LowerAtomic.cpp
Go to the documentation of this file.
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 
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/IRBuilder.h"
17 #include "llvm/InitializePasses.h"
18 #include "llvm/Pass.h"
19 using namespace llvm;
20 
21 #define DEBUG_TYPE "loweratomic"
22 
24  IRBuilder<> Builder(CXI);
25  Value *Ptr = CXI->getPointerOperand();
26  Value *Cmp = CXI->getCompareOperand();
27  Value *Val = CXI->getNewValOperand();
28 
29  LoadInst *Orig = Builder.CreateLoad(Val->getType(), Ptr);
30  Value *Equal = Builder.CreateICmpEQ(Orig, Cmp);
31  Value *Res = Builder.CreateSelect(Equal, Val, Orig);
32  Builder.CreateStore(Res, Ptr);
33 
34  Res = Builder.CreateInsertValue(PoisonValue::get(CXI->getType()), Orig, 0);
35  Res = Builder.CreateInsertValue(Res, Equal, 1);
36 
37  CXI->replaceAllUsesWith(Res);
38  CXI->eraseFromParent();
39  return true;
40 }
41 
43  IRBuilderBase &Builder, Value *Loaded,
44  Value *Inc) {
45  Value *NewVal;
46  switch (Op) {
48  return Inc;
49  case AtomicRMWInst::Add:
50  return Builder.CreateAdd(Loaded, Inc, "new");
51  case AtomicRMWInst::Sub:
52  return Builder.CreateSub(Loaded, Inc, "new");
53  case AtomicRMWInst::And:
54  return Builder.CreateAnd(Loaded, Inc, "new");
56  return Builder.CreateNot(Builder.CreateAnd(Loaded, Inc), "new");
57  case AtomicRMWInst::Or:
58  return Builder.CreateOr(Loaded, Inc, "new");
59  case AtomicRMWInst::Xor:
60  return Builder.CreateXor(Loaded, Inc, "new");
61  case AtomicRMWInst::Max:
62  NewVal = Builder.CreateICmpSGT(Loaded, Inc);
63  return Builder.CreateSelect(NewVal, Loaded, Inc, "new");
64  case AtomicRMWInst::Min:
65  NewVal = Builder.CreateICmpSLE(Loaded, Inc);
66  return Builder.CreateSelect(NewVal, Loaded, Inc, "new");
68  NewVal = Builder.CreateICmpUGT(Loaded, Inc);
69  return Builder.CreateSelect(NewVal, Loaded, Inc, "new");
71  NewVal = Builder.CreateICmpULE(Loaded, Inc);
72  return Builder.CreateSelect(NewVal, Loaded, Inc, "new");
74  return Builder.CreateFAdd(Loaded, Inc, "new");
76  return Builder.CreateFSub(Loaded, Inc, "new");
78  return Builder.CreateMaxNum(Loaded, Inc);
80  return Builder.CreateMinNum(Loaded, Inc);
81  default:
82  llvm_unreachable("Unknown atomic op");
83  }
84 }
85 
87  IRBuilder<> Builder(RMWI);
88  Value *Ptr = RMWI->getPointerOperand();
89  Value *Val = RMWI->getValOperand();
90 
91  LoadInst *Orig = Builder.CreateLoad(Val->getType(), Ptr);
92  Value *Res = buildAtomicRMWValue(RMWI->getOperation(), Builder, Orig, Val);
93  Builder.CreateStore(Res, Ptr);
94  RMWI->replaceAllUsesWith(Orig);
95  RMWI->eraseFromParent();
96  return true;
97 }
llvm::object::Equal
@ Equal
Definition: COFFModuleDefinition.cpp:36
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Pass.h
llvm::AtomicRMWInst::Xor
@ Xor
*p = old ^ v
Definition: Instructions.h:741
llvm::AtomicRMWInst::getOperation
BinOp getOperation() const
Definition: Instructions.h:801
llvm::AtomicRMWInst::BinOp
BinOp
This enumeration lists the possible modifications atomicrmw can make.
Definition: Instructions.h:727
LowerAtomic.h
llvm::IRBuilder<>
llvm::AtomicRMWInst::FMin
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
Definition: Instructions.h:763
llvm::AtomicRMWInst::getPointerOperand
Value * getPointerOperand()
Definition: Instructions.h:866
llvm::AtomicCmpXchgInst::getNewValOperand
Value * getNewValOperand()
Definition: Instructions.h:647
llvm::AtomicRMWInst::Nand
@ Nand
*p = ~(old & v)
Definition: Instructions.h:737
llvm::AtomicRMWInst::FMax
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
Definition: Instructions.h:759
llvm::AtomicRMWInst::Xchg
@ Xchg
*p = v
Definition: Instructions.h:729
llvm::AtomicRMWInst::Add
@ Add
*p = old + v
Definition: Instructions.h:731
llvm::AtomicRMWInst::UMin
@ UMin
*p = old <unsigned v ? old : v
Definition: Instructions.h:749
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:77
llvm::AtomicRMWInst::Sub
@ Sub
*p = old - v
Definition: Instructions.h:733
llvm::AtomicRMWInst::Min
@ Min
*p = old <signed v ? old : v
Definition: Instructions.h:745
llvm::AtomicRMWInst::Or
@ Or
*p = old | v
Definition: Instructions.h:739
llvm::lowerAtomicRMWInst
bool lowerAtomicRMWInst(AtomicRMWInst *RMWI)
Convert the given RMWI into primitive load and stores, assuming that doing so is legal.
Definition: LowerAtomic.cpp:86
IRBuilder.h
llvm::AtomicCmpXchgInst::getCompareOperand
Value * getCompareOperand()
Definition: Instructions.h:644
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::lowerAtomicCmpXchgInst
bool lowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI)
Convert the given Cmpxchg into primitive load and compare.
Definition: LowerAtomic.cpp:23
llvm::buildAtomicRMWValue
Value * buildAtomicRMWValue(AtomicRMWInst::BinOp Op, IRBuilderBase &Builder, Value *Loaded, Value *Inc)
Emit IR to implement the given atomicrmw operation on values in registers, returning the new value.
Definition: LowerAtomic.cpp:42
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
llvm::IRBuilderBase
Common base class shared among various IRBuilders.
Definition: IRBuilder.h:93
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:715
llvm::AtomicRMWInst::FSub
@ FSub
*p = old - v
Definition: Instructions.h:755
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::AtomicRMWInst::And
@ And
*p = old & v
Definition: Instructions.h:735
Function.h
llvm::AtomicCmpXchgInst::getPointerOperand
Value * getPointerOperand()
Definition: Instructions.h:640
llvm::AtomicRMWInst::getValOperand
Value * getValOperand()
Definition: Instructions.h:870
llvm::AtomicRMWInst::FAdd
@ FAdd
*p = old + v
Definition: Instructions.h:752
llvm::AtomicRMWInst::UMax
@ UMax
*p = old >unsigned v ? old : v
Definition: Instructions.h:747
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:510
llvm::AtomicRMWInst::Max
@ Max
*p = old >signed v ? old : v
Definition: Instructions.h:743
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1729