17
17
#include < llvm/IR/InstIterator.h>
18
18
#include < llvm/IR/Instructions.h>
19
19
#include < llvm/IR/IntrinsicInst.h>
20
+ #include " llvm/IR/MemoryModelRelaxationAnnotations.h"
20
21
#include < llvm/IR/Module.h>
21
22
#include < llvm/IR/Operator.h>
22
23
#include < llvm/IR/PassManager.h>
@@ -141,12 +142,28 @@ std::pair<Value *, Value *> insertRMWCmpXchgLoop(
141
142
}
142
143
143
144
// from AtomicExpandImpl
144
- struct ReplacementIRBuilder : IRBuilder<InstSimplifyFolder> {
145
+ // IRBuilder to be used for replacement atomic instructions.
146
+ struct ReplacementIRBuilder
147
+ : IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> {
148
+ MDNode *MMRAMD = nullptr ;
149
+
145
150
// Preserves the DebugLoc from I, and preserves still valid metadata.
151
+ // Enable StrictFP builder mode when appropriate.
146
152
explicit ReplacementIRBuilder (Instruction *I, const DataLayout &DL)
147
- : IRBuilder(I->getContext (), DL) {
153
+ : IRBuilder(I->getContext (), InstSimplifyFolder(DL),
154
+ IRBuilderCallbackInserter(
155
+ [this ](Instruction *I) { addMMRAMD (I); })) {
148
156
SetInsertPoint (I);
149
157
this ->CollectMetadataToCopy (I, {LLVMContext::MD_pcsections});
158
+ if (BB->getParent ()->getAttributes ().hasFnAttr (Attribute::StrictFP))
159
+ this ->setIsFPConstrained (true );
160
+
161
+ MMRAMD = I->getMetadata (LLVMContext::MD_mmra);
162
+ }
163
+
164
+ void addMMRAMD (Instruction *I) {
165
+ if (canInstructionHaveMMRAs (*I))
166
+ I->setMetadata (LLVMContext::MD_mmra, MMRAMD);
150
167
}
151
168
};
152
169
@@ -321,7 +338,6 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
321
338
Type *Ty = Modify.getFunctionType ()->getReturnType ()->getStructElementType (0 );
322
339
323
340
ReplacementIRBuilder Builder (&Modify, Modify.getModule ()->getDataLayout ());
324
- Builder.setIsFPConstrained (Modify.hasFnAttr (Attribute::StrictFP));
325
341
326
342
CallInst *ModifyOp;
327
343
{
@@ -366,7 +382,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
366
382
ModifyOp = cast<CallInst>(ValOp->getUser ());
367
383
LoadedOp = ValOp;
368
384
assert (LoadedOp->get () == RMW);
369
- RMW->moveBefore (ModifyOp); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
385
+ RMW->moveBeforePreserving (ModifyOp-> getIterator () ); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
370
386
BinOp = false ;
371
387
if (++attempts > 3 )
372
388
break ;
@@ -383,7 +399,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
383
399
assert (isa<UndefValue>(RMW->getOperand (1 ))); // RMW was previously being used as the placeholder for Val
384
400
Value *Val;
385
401
if (ValOp != nullptr ) {
386
- RMW->moveBefore (cast<Instruction>(ValOp->getUser ())); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
402
+ RMW->moveBeforePreserving (cast<Instruction>(ValOp->getUser ())-> getIterator ( )); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
387
403
Val = ValOp->get ();
388
404
} else if (RMWOp == AtomicRMWInst::Xchg) {
389
405
Val = NewVal;
@@ -411,7 +427,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
411
427
Builder, Ty, Ptr , *Alignment, Ordering, SSID, Modify,
412
428
[&](IRBuilderBase &Builder, Value *Loaded) JL_NOTSAFEPOINT {
413
429
LoadedOp->set (Loaded);
414
- ModifyOp->moveBefore (*Builder.GetInsertBlock (), Builder.GetInsertPoint ());
430
+ ModifyOp->moveBeforePreserving (*Builder.GetInsertBlock (), Builder.GetInsertPoint ());
415
431
return ModifyOp;
416
432
},
417
433
CreateWeakCmpXchg);
0 commit comments