Skip to content

Commit a0e1b4a

Browse files
authored
[MC/DC][Coverage] Split out Read-modfy-Write to rmw_or(ptr,i8) (#96040)
`rmw_or` is defined as "private alwaysinline". At the moment, it has just only simple "Read, Or, and Write", which is just same as the current implementation.
1 parent 91db7ad commit a0e1b4a

File tree

2 files changed

+59
-14
lines changed

2 files changed

+59
-14
lines changed

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ class InstrLowerer final {
237237
GlobalVariable *NamesVar = nullptr;
238238
size_t NamesSize = 0;
239239

240+
/// The instance of [[alwaysinline]] rmw_or(ptr, i8).
241+
/// This is name-insensitive.
242+
Function *RMWOrFunc = nullptr;
243+
240244
// vector of counter load/store pairs to be register promoted.
241245
std::vector<LoadStorePair> PromotionCandidates;
242246

@@ -297,6 +301,14 @@ class InstrLowerer final {
297301
StringRef Name,
298302
GlobalValue::LinkageTypes Linkage);
299303

304+
/// Create [[alwaysinline]] rmw_or(ptr, i8).
305+
/// This doesn't update `RMWOrFunc`.
306+
Function *createRMWOrFunc();
307+
308+
/// Get the call to `rmw_or`.
309+
/// Create the instance if it is unknown.
310+
CallInst *getRMWOrCall(Value *Addr, Value *Val);
311+
300312
/// Compute the address of the test vector bitmap that this profiling
301313
/// instruction acts on.
302314
Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I);
@@ -937,6 +949,45 @@ Value *InstrLowerer::getCounterAddress(InstrProfCntrInstBase *I) {
937949
return Builder.CreateIntToPtr(Add, Addr->getType());
938950
}
939951

952+
/// Create `void [[alwaysinline]] rmw_or(uint8_t *ArgAddr, uint8_t ArgVal)`
953+
/// "Basic" sequence is `*ArgAddr |= ArgVal`
954+
Function *InstrLowerer::createRMWOrFunc() {
955+
auto &Ctx = M.getContext();
956+
auto *Int8Ty = Type::getInt8Ty(Ctx);
957+
Function *Fn = Function::Create(
958+
FunctionType::get(Type::getVoidTy(Ctx),
959+
{PointerType::getUnqual(Ctx), Int8Ty}, false),
960+
Function::LinkageTypes::PrivateLinkage, "rmw_or", M);
961+
Fn->addFnAttr(Attribute::AlwaysInline);
962+
auto *ArgAddr = Fn->getArg(0);
963+
auto *ArgVal = Fn->getArg(1);
964+
IRBuilder<> Builder(BasicBlock::Create(Ctx, "", Fn));
965+
966+
// Load profile bitmap byte.
967+
// %mcdc.bits = load i8, ptr %4, align 1
968+
auto *Bitmap = Builder.CreateLoad(Int8Ty, ArgAddr, "mcdc.bits");
969+
970+
// Perform logical OR of profile bitmap byte and shifted bit offset.
971+
// %8 = or i8 %mcdc.bits, %7
972+
auto *Result = Builder.CreateOr(Bitmap, ArgVal);
973+
974+
// Store the updated profile bitmap byte.
975+
// store i8 %8, ptr %3, align 1
976+
Builder.CreateStore(Result, ArgAddr);
977+
978+
// Terminator
979+
Builder.CreateRetVoid();
980+
981+
return Fn;
982+
}
983+
984+
CallInst *InstrLowerer::getRMWOrCall(Value *Addr, Value *Val) {
985+
if (!RMWOrFunc)
986+
RMWOrFunc = createRMWOrFunc();
987+
988+
return CallInst::Create(RMWOrFunc, {Addr, Val});
989+
}
990+
940991
Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) {
941992
auto *Bitmaps = getOrCreateRegionBitmaps(I);
942993
IRBuilder<> Builder(I);
@@ -1044,17 +1095,7 @@ void InstrLowerer::lowerMCDCTestVectorBitmapUpdate(
10441095
// %7 = shl i8 1, %6
10451096
auto *ShiftedVal = Builder.CreateShl(Builder.getInt8(0x1), BitToSet);
10461097

1047-
// Load profile bitmap byte.
1048-
// %mcdc.bits = load i8, ptr %4, align 1
1049-
auto *Bitmap = Builder.CreateLoad(Int8Ty, BitmapByteAddr, "mcdc.bits");
1050-
1051-
// Perform logical OR of profile bitmap byte and shifted bit offset.
1052-
// %8 = or i8 %mcdc.bits, %7
1053-
auto *Result = Builder.CreateOr(Bitmap, ShiftedVal);
1054-
1055-
// Store the updated profile bitmap byte.
1056-
// store i8 %8, ptr %3, align 1
1057-
Builder.CreateStore(Result, BitmapByteAddr);
1098+
Builder.Insert(getRMWOrCall(BitmapByteAddr, ShiftedVal));
10581099
Update->eraseFromParent();
10591100
}
10601101

llvm/test/Instrumentation/InstrProfiling/mcdc.ll

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@ entry:
3030
; CHECK-NEXT: %[[LAB8:[0-9]+]] = and i32 %[[TEMP]], 7
3131
; CHECK-NEXT: %[[LAB9:[0-9]+]] = trunc i32 %[[LAB8]] to i8
3232
; CHECK-NEXT: %[[LAB10:[0-9]+]] = shl i8 1, %[[LAB9]]
33-
; CHECK-NEXT: %[[BITS:mcdc.*]] = load i8, ptr %[[LAB7]], align 1
34-
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[LAB10]]
35-
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[LAB7]], align 1
33+
; CHECK-NEXT: call void @[[RMW_OR:.+]](ptr %[[LAB7]], i8 %[[LAB10]])
3634
ret void
3735
}
3836

37+
; CHECK: define private void @[[RMW_OR]](ptr %[[ARGPTR:.+]], i8 %[[ARGVAL:.+]])
38+
; CHECK: %[[BITS:.+]] = load i8, ptr %[[ARGPTR]], align 1
39+
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
40+
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
41+
; CHECK-NEXT: ret void
42+
3943
declare void @llvm.instrprof.cover(ptr, i64, i32, i32)
4044

4145
declare void @llvm.instrprof.mcdc.parameters(ptr, i64, i32)

0 commit comments

Comments
 (0)