|
38 | 38 | #include "llvm/IR/Instruction.h"
|
39 | 39 | #include "llvm/IR/Instructions.h"
|
40 | 40 | #include "llvm/IR/IntrinsicInst.h"
|
| 41 | +#include "llvm/IR/MDBuilder.h" |
41 | 42 | #include "llvm/IR/Module.h"
|
42 | 43 | #include "llvm/IR/Type.h"
|
43 | 44 | #include "llvm/InitializePasses.h"
|
@@ -967,6 +968,29 @@ Function *InstrLowerer::createRMWOrFunc() {
|
967 | 968 | // %mcdc.bits = load i8, ptr %4, align 1
|
968 | 969 | auto *Bitmap = Builder.CreateLoad(Int8Ty, ArgAddr, "mcdc.bits");
|
969 | 970 |
|
| 971 | + if (Options.Atomic || AtomicCounterUpdateAll) { |
| 972 | + // If ((Bitmap & Val) != Val), then execute atomic (Bitmap |= Val). |
| 973 | + // Note, just-loaded Bitmap might not be up-to-date. Use it just for |
| 974 | + // early testing. |
| 975 | + auto *Masked = Builder.CreateAnd(Bitmap, ArgVal); |
| 976 | + auto *ShouldStore = Builder.CreateICmpNE(Masked, ArgVal); |
| 977 | + auto *ThenTerm = BasicBlock::Create(Ctx, "", Fn); |
| 978 | + auto *ElseTerm = BasicBlock::Create(Ctx, "", Fn); |
| 979 | + // Assume updating will be rare. |
| 980 | + auto *Unlikely = MDBuilder(Ctx).createUnlikelyBranchWeights(); |
| 981 | + Builder.CreateCondBr(ShouldStore, ThenTerm, ElseTerm, Unlikely); |
| 982 | + |
| 983 | + IRBuilder<> ThenBuilder(ThenTerm); |
| 984 | + ThenBuilder.CreateAtomicRMW(AtomicRMWInst::Or, ArgAddr, ArgVal, |
| 985 | + MaybeAlign(), AtomicOrdering::Monotonic); |
| 986 | + ThenBuilder.CreateRetVoid(); |
| 987 | + |
| 988 | + IRBuilder<> ElseBuilder(ElseTerm); |
| 989 | + ElseBuilder.CreateRetVoid(); |
| 990 | + |
| 991 | + return Fn; |
| 992 | + } |
| 993 | + |
970 | 994 | // Perform logical OR of profile bitmap byte and shifted bit offset.
|
971 | 995 | // %8 = or i8 %mcdc.bits, %7
|
972 | 996 | auto *Result = Builder.CreateOr(Bitmap, ArgVal);
|
|
0 commit comments