@@ -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-
12021128Value *InstrLowerer::getBitmapAddress (InstrProfMCDCTVBitmapUpdate *I) {
12031129 auto *Bitmaps = getOrCreateRegionBitmaps (I);
12041130 if (!isRuntimeCounterRelocationEnabled ())
@@ -1291,9 +1217,10 @@ void InstrLowerer::lowerCoverageData(GlobalVariable *CoverageNamesVar) {
12911217
12921218void 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
0 commit comments