LLVM: lib/Transforms/Utils/LowerAtomic.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17
18using namespace llvm;
19
20#define DEBUG_TYPE "loweratomic"
21
27
28 auto [Orig, Equal] =
30
33 Res = Builder.CreateInsertValue(Res, Equal, 1);
34
37 return true;
38}
39
43 Align Alignment) {
44 LoadInst *Orig = Builder.CreateAlignedLoad(Val->getType(), Ptr, Alignment);
45 Value *Equal = Builder.CreateICmpEQ(Orig, Cmp);
46 Value *Res = Builder.CreateSelect(Equal, Val, Orig);
47 Builder.CreateAlignedStore(Res, Ptr, Alignment);
48
49 return {Orig, Equal};
50}
51
56 switch (Op) {
58 return Val;
60 return Builder.CreateAdd(Loaded, Val, "new");
62 return Builder.CreateSub(Loaded, Val, "new");
64 return Builder.CreateAnd(Loaded, Val, "new");
66 return Builder.CreateNot(Builder.CreateAnd(Loaded, Val), "new");
68 return Builder.CreateOr(Loaded, Val, "new");
70 return Builder.CreateXor(Loaded, Val, "new");
72 NewVal = Builder.CreateICmpSGT(Loaded, Val);
73 return Builder.CreateSelect(NewVal, Loaded, Val, "new");
75 NewVal = Builder.CreateICmpSLE(Loaded, Val);
76 return Builder.CreateSelect(NewVal, Loaded, Val, "new");
78 NewVal = Builder.CreateICmpUGT(Loaded, Val);
79 return Builder.CreateSelect(NewVal, Loaded, Val, "new");
81 NewVal = Builder.CreateICmpULE(Loaded, Val);
82 return Builder.CreateSelect(NewVal, Loaded, Val, "new");
84 return Builder.CreateFAdd(Loaded, Val, "new");
86 return Builder.CreateFSub(Loaded, Val, "new");
88 return Builder.CreateMaxNum(Loaded, Val);
90 return Builder.CreateMinNum(Loaded, Val);
92 return Builder.CreateMaximum(Loaded, Val);
94 return Builder.CreateMinimum(Loaded, Val);
97 Value *Inc = Builder.CreateAdd(Loaded, One);
98 Value *Cmp = Builder.CreateICmpUGE(Loaded, Val);
100 return Builder.CreateSelect(Cmp, Zero, Inc, "new");
101 }
105
106 Value *Dec = Builder.CreateSub(Loaded, One);
107 Value *CmpEq0 = Builder.CreateICmpEQ(Loaded, Zero);
108 Value *CmpOldGtVal = Builder.CreateICmpUGT(Loaded, Val);
109 Value *Or = Builder.CreateOr(CmpEq0, CmpOldGtVal);
110 return Builder.CreateSelect(Or, Val, Dec, "new");
111 }
113 Value *Cmp = Builder.CreateICmpUGE(Loaded, Val);
114 Value *Sub = Builder.CreateSub(Loaded, Val);
115 return Builder.CreateSelect(Cmp, Sub, Loaded, "new");
116 }
118 return Builder.CreateIntrinsic(Intrinsic::usub_sat, Loaded->getType(),
119 {Loaded, Val}, nullptr, "new");
120 default:
122 }
123}
124
127 Builder.setIsFPConstrained(
129
132
133 LoadInst *Orig = Builder.CreateLoad(Val->getType(), Ptr);
135 Builder.CreateStore(Res, Ptr);
138 return true;
139}
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
Value * getCompareOperand()
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ FMinimum
*p = minimum(old, v) minimum matches the behavior of llvm.minimum.
@ Min
*p = old <signed v ? old : v
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ FMaximum
*p = maximum(old, v) maximum matches the behavior of llvm.maximum.
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
@ UMax
*p = old >unsigned v ? old : v
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
@ UDecWrap
Decrement one until a minimum value or zero.
Value * getPointerOperand()
BinOp getOperation() const
This is an important base class in LLVM.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Common base class shared among various IRBuilders.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
An instruction for reading from memory.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
std::pair< Value *, Value * > buildCmpXchgValue(IRBuilderBase &Builder, Value *Ptr, Value *Cmp, Value *Val, Align Alignment)
Emit IR to implement the given cmpxchg operation on values in registers, returning the new value.
Definition LowerAtomic.cpp:40
Value * buildAtomicRMWValue(AtomicRMWInst::BinOp Op, IRBuilderBase &Builder, Value *Loaded, Value *Val)
Emit IR to implement the given atomicrmw operation on values in registers, returning the new value.
Definition LowerAtomic.cpp:52
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
bool lowerAtomicCmpXchgInst(AtomicCmpXchgInst *CXI)
Convert the given Cmpxchg into primitive load and compare.
Definition LowerAtomic.cpp:22
bool lowerAtomicRMWInst(AtomicRMWInst *RMWI)
Convert the given RMWI into primitive load and stores, assuming that doing so is legal.
Definition LowerAtomic.cpp:125
This struct is a compact representation of a valid (non-zero power of two) alignment.