Skip to content

Commit 6b977de

Browse files
committed
[MC/DC] Rework tvbitmap.update (llvm#96040) to get rid of the inlined function
Per the discussion in llvm#102542, it is safe to insert BBs under `lowerIntrinsics()` since llvm#69535 has made tolerant of modifying BBs. So, I can get rid of using the inlined function `rmw_or`.
1 parent 4fc08b6 commit 6b977de

File tree

2 files changed

+45
-93
lines changed

2 files changed

+45
-93
lines changed

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 33 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,6 @@ class InstrLowerer final {
267267
GlobalVariable *NamesVar = nullptr;
268268
size_t NamesSize = 0;
269269

270-
/// The instance of [[alwaysinline]] rmw_or(ptr, i8).
271-
/// This is name-insensitive.
272-
Function *RMWOrFunc = nullptr;
273-
274270
// vector of counter load/store pairs to be register promoted.
275271
std::vector<LoadStorePair> PromotionCandidates;
276272

@@ -337,14 +333,6 @@ class InstrLowerer final {
337333
StringRef Name,
338334
GlobalValue::LinkageTypes Linkage);
339335

340-
/// Create [[alwaysinline]] rmw_or(ptr, i8).
341-
/// This doesn't update `RMWOrFunc`.
342-
Function *createRMWOrFunc();
343-
344-
/// Get the call to `rmw_or`.
345-
/// Create the instance if it is unknown.
346-
CallInst *getRMWOrCall(Value *Addr, Value *Val);
347-
348336
/// Compute the address of the test vector bitmap that this profiling
349337
/// instruction acts on.
350338
Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I);
@@ -1137,68 +1125,6 @@ Value *InstrLowerer::getCounterAddress(InstrProfCntrInstBase *I) {
11371125
return Builder.CreateIntToPtr(Add, Addr->getType());
11381126
}
11391127

1140-
/// Create `void [[alwaysinline]] rmw_or(uint8_t *ArgAddr, uint8_t ArgVal)`
1141-
/// "Basic" sequence is `*ArgAddr |= ArgVal`
1142-
Function *InstrLowerer::createRMWOrFunc() {
1143-
auto &Ctx = M.getContext();
1144-
auto *Int8Ty = Type::getInt8Ty(Ctx);
1145-
Function *Fn = Function::Create(
1146-
FunctionType::get(Type::getVoidTy(Ctx),
1147-
{PointerType::getUnqual(Ctx), Int8Ty}, false),
1148-
Function::LinkageTypes::PrivateLinkage, "rmw_or", M);
1149-
Fn->addFnAttr(Attribute::AlwaysInline);
1150-
auto *ArgAddr = Fn->getArg(0);
1151-
auto *ArgVal = Fn->getArg(1);
1152-
IRBuilder<> Builder(BasicBlock::Create(Ctx, "", Fn));
1153-
1154-
// Load profile bitmap byte.
1155-
// %mcdc.bits = load i8, ptr %4, align 1
1156-
auto *Bitmap = Builder.CreateLoad(Int8Ty, ArgAddr, "mcdc.bits");
1157-
1158-
if (Options.Atomic || AtomicCounterUpdateAll) {
1159-
// If ((Bitmap & Val) != Val), then execute atomic (Bitmap |= Val).
1160-
// Note, just-loaded Bitmap might not be up-to-date. Use it just for
1161-
// early testing.
1162-
auto *Masked = Builder.CreateAnd(Bitmap, ArgVal);
1163-
auto *ShouldStore = Builder.CreateICmpNE(Masked, ArgVal);
1164-
auto *ThenTerm = BasicBlock::Create(Ctx, "", Fn);
1165-
auto *ElseTerm = BasicBlock::Create(Ctx, "", Fn);
1166-
// Assume updating will be rare.
1167-
auto *Unlikely = MDBuilder(Ctx).createUnlikelyBranchWeights();
1168-
Builder.CreateCondBr(ShouldStore, ThenTerm, ElseTerm, Unlikely);
1169-
1170-
IRBuilder<> ThenBuilder(ThenTerm);
1171-
ThenBuilder.CreateAtomicRMW(AtomicRMWInst::Or, ArgAddr, ArgVal,
1172-
MaybeAlign(), AtomicOrdering::Monotonic);
1173-
ThenBuilder.CreateRetVoid();
1174-
1175-
IRBuilder<> ElseBuilder(ElseTerm);
1176-
ElseBuilder.CreateRetVoid();
1177-
1178-
return Fn;
1179-
}
1180-
1181-
// Perform logical OR of profile bitmap byte and shifted bit offset.
1182-
// %8 = or i8 %mcdc.bits, %7
1183-
auto *Result = Builder.CreateOr(Bitmap, ArgVal);
1184-
1185-
// Store the updated profile bitmap byte.
1186-
// store i8 %8, ptr %3, align 1
1187-
Builder.CreateStore(Result, ArgAddr);
1188-
1189-
// Terminator
1190-
Builder.CreateRetVoid();
1191-
1192-
return Fn;
1193-
}
1194-
1195-
CallInst *InstrLowerer::getRMWOrCall(Value *Addr, Value *Val) {
1196-
if (!RMWOrFunc)
1197-
RMWOrFunc = createRMWOrFunc();
1198-
1199-
return CallInst::Create(RMWOrFunc, {Addr, Val});
1200-
}
1201-
12021128
Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) {
12031129
auto *Bitmaps = getOrCreateRegionBitmaps(I);
12041130
if (!isRuntimeCounterRelocationEnabled())
@@ -1291,9 +1217,10 @@ void InstrLowerer::lowerCoverageData(GlobalVariable *CoverageNamesVar) {
12911217

12921218
void InstrLowerer::lowerMCDCTestVectorBitmapUpdate(
12931219
InstrProfMCDCTVBitmapUpdate *Update) {
1220+
auto &Ctx = M.getContext();
12941221
IRBuilder<> Builder(Update);
1295-
auto *Int8Ty = Type::getInt8Ty(M.getContext());
1296-
auto *Int32Ty = Type::getInt32Ty(M.getContext());
1222+
auto *Int8Ty = Type::getInt8Ty(Ctx);
1223+
auto *Int32Ty = Type::getInt32Ty(Ctx);
12971224
auto *MCDCCondBitmapAddr = Update->getMCDCCondBitmapAddr();
12981225
auto *BitmapAddr = getBitmapAddress(Update);
12991226

@@ -1321,7 +1248,36 @@ void InstrLowerer::lowerMCDCTestVectorBitmapUpdate(
13211248
// %7 = shl i8 1, %6
13221249
auto *ShiftedVal = Builder.CreateShl(Builder.getInt8(0x1), BitToSet);
13231250

1324-
Builder.Insert(getRMWOrCall(BitmapByteAddr, ShiftedVal));
1251+
// Load profile bitmap byte.
1252+
// %mcdc.bits = load i8, ptr %4, align 1
1253+
auto *Bitmap = Builder.CreateLoad(Int8Ty, BitmapByteAddr, "mcdc.bits");
1254+
1255+
if (Options.Atomic || AtomicCounterUpdateAll) {
1256+
// If ((Bitmap & Val) != Val), then execute atomic (Bitmap |= Val).
1257+
// Note, just-loaded Bitmap might not be up-to-date. Use it just for
1258+
// early testing.
1259+
auto *Masked = Builder.CreateAnd(Bitmap, ShiftedVal);
1260+
auto *ShouldStore = Builder.CreateICmpNE(Masked, ShiftedVal);
1261+
1262+
// Assume updating will be rare.
1263+
auto *Unlikely = MDBuilder(Ctx).createUnlikelyBranchWeights();
1264+
Instruction *ThenBranch =
1265+
SplitBlockAndInsertIfThen(ShouldStore, Update, false, Unlikely);
1266+
1267+
// Execute if (unlikely(ShouldStore)).
1268+
Builder.SetInsertPoint(ThenBranch);
1269+
Builder.CreateAtomicRMW(AtomicRMWInst::Or, BitmapByteAddr, ShiftedVal,
1270+
MaybeAlign(), AtomicOrdering::Monotonic);
1271+
} else {
1272+
// Perform logical OR of profile bitmap byte and shifted bit offset.
1273+
// %8 = or i8 %mcdc.bits, %7
1274+
auto *Result = Builder.CreateOr(Bitmap, ShiftedVal);
1275+
1276+
// Store the updated profile bitmap byte.
1277+
// store i8 %8, ptr %3, align 1
1278+
Builder.CreateStore(Result, BitmapByteAddr);
1279+
}
1280+
13251281
Update->eraseFromParent();
13261282
}
13271283

llvm/test/Instrumentation/InstrProfiling/mcdc.ll

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,21 @@ entry:
3636
; CHECK-NEXT: %[[LAB8:[0-9]+]] = and i32 %[[TEMP]], 7
3737
; CHECK-NEXT: %[[LAB9:[0-9]+]] = trunc i32 %[[LAB8]] to i8
3838
; CHECK-NEXT: %[[LAB10:[0-9]+]] = shl i8 1, %[[LAB9]]
39-
; CHECK-NEXT: call void @[[RMW_OR:.+]](ptr %[[LAB7]], i8 %[[LAB10]])
39+
; CHECK-NEXT: %[[BITS:.+]] = load i8, ptr %[[LAB7]], align 1
40+
; ATOMIC-NEXT: %[[MASKED:.+]] = and i8 %[[BITS]], %[[LAB10]]
41+
; ATOMIC-NEXT: %[[SHOULDWRITE:.+]] = icmp ne i8 %[[MASKED]], %[[LAB10]]
42+
; ATOMIC-NEXT: br i1 %[[SHOULDWRITE]], label %[[WRITE:.+]], label %[[SKIP:.+]], !prof ![[MDPROF:[0-9]+]]
43+
; ATOMIC: [[WRITE]]:
44+
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[LAB10]]
45+
; RELOC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[LAB10]]
46+
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[LAB7]], align 1
47+
; RELOC-NEXT: store i8 %[[LAB11]], ptr %[[LAB7]], align 1
48+
; ATOMIC-NEXT: %{{.+}} = atomicrmw or ptr %[[LAB7]], i8 %[[LAB10]] monotonic, align 1
49+
; ATOMIC: [[SKIP]]:
4050
ret void
51+
; CHECK-NEXT: ret void
4152
}
4253

43-
; CHECK: define private void @[[RMW_OR]](ptr %[[ARGPTR:.+]], i8 %[[ARGVAL:.+]])
44-
; CHECK: %[[BITS:.+]] = load i8, ptr %[[ARGPTR]], align 1
45-
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
46-
; RELOC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
47-
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
48-
; RELOC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
49-
; ATOMIC-NEXT: %[[MASKED:.+]] = and i8 %[[BITS]], %[[ARGVAL]]
50-
; ATOMIC-NEXT: %[[SHOULDWRITE:.+]] = icmp ne i8 %[[MASKED]], %[[ARGVAL]]
51-
; ATOMIC-NEXT: br i1 %[[SHOULDWRITE]], label %[[WRITE:.+]], label %[[SKIP:.+]], !prof ![[MDPROF:[0-9]+]]
52-
; ATOMIC: [[WRITE]]:
53-
; ATOMIC-NEXT: %{{.+}} = atomicrmw or ptr %[[ARGPTR]], i8 %[[ARGVAL]] monotonic, align 1
54-
; ATOMIC-NEXT: ret void
55-
; ATOMIC: [[SKIP]]:
56-
; CHECK-NEXT: ret void
57-
5854
; ATOMIC: ![[MDPROF]] = !{!"branch_weights", i32 1, i32 1048575}
5955

6056
declare void @llvm.instrprof.cover(ptr, i64, i32, i32)

0 commit comments

Comments
 (0)