@@ -167,8 +167,6 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
167
167
PGOHash Hash;
168
168
// / The map of statements to counters.
169
169
llvm::DenseMap<const Stmt *, unsigned > &CounterMap;
170
- // / The next bitmap byte index to assign.
171
- unsigned NextMCDCBitmapIdx;
172
170
// / The state of MC/DC Coverage in this function.
173
171
MCDC::State &MCDCState;
174
172
// / Maximum number of supported MC/DC conditions in a boolean expression.
@@ -183,7 +181,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
183
181
MCDC::State &MCDCState, unsigned MCDCMaxCond,
184
182
DiagnosticsEngine &Diag)
185
183
: NextCounter(0 ), Hash(HashVersion), CounterMap(CounterMap),
186
- NextMCDCBitmapIdx ( 0 ), MCDCState(MCDCState), MCDCMaxCond(MCDCMaxCond),
184
+ MCDCState (MCDCState), MCDCMaxCond(MCDCMaxCond),
187
185
ProfileVersion(ProfileVersion), Diag(Diag) {}
188
186
189
187
// Blocks and lambdas are handled as separate functions, so we need not
@@ -314,11 +312,8 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
314
312
return true ;
315
313
}
316
314
317
- // Otherwise, allocate the number of bytes required for the bitmap
318
- // based on the number of conditions. Must be at least 1-byte long.
319
- MCDCState.DecisionByStmt [BinOp].BitmapIdx = NextMCDCBitmapIdx;
320
- unsigned SizeInBits = std::max<unsigned >(1L << NumCond, CHAR_BIT);
321
- NextMCDCBitmapIdx += SizeInBits / CHAR_BIT;
315
+ // Otherwise, allocate the Decision.
316
+ MCDCState.DecisionByStmt [BinOp].BitmapIdx = 0 ;
322
317
}
323
318
return true ;
324
319
}
@@ -1083,7 +1078,9 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) {
1083
1078
// for most embedded applications. Setting a maximum value prevents the
1084
1079
// bitmap footprint from growing too large without the user's knowledge. In
1085
1080
// the future, this value could be adjusted with a command-line option.
1086
- unsigned MCDCMaxConditions = (CGM.getCodeGenOpts ().MCDCCoverage ) ? 6 : 0 ;
1081
+ unsigned MCDCMaxConditions =
1082
+ (CGM.getCodeGenOpts ().MCDCCoverage ? CGM.getCodeGenOpts ().MCDCMaxConds
1083
+ : 0 );
1087
1084
1088
1085
RegionCounterMap.reset (new llvm::DenseMap<const Stmt *, unsigned >);
1089
1086
RegionMCDCState.reset (new MCDC::State);
@@ -1099,7 +1096,6 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) {
1099
1096
Walker.TraverseDecl (const_cast <CapturedDecl *>(CD));
1100
1097
assert (Walker.NextCounter > 0 && " no entry counter mapped for decl" );
1101
1098
NumRegionCounters = Walker.NextCounter ;
1102
- RegionMCDCState->BitmapBytes = Walker.NextMCDCBitmapIdx ;
1103
1099
FunctionHash = Walker.Hash .finalize ();
1104
1100
}
1105
1101
@@ -1232,7 +1228,7 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
1232
1228
// anything.
1233
1229
llvm::Value *Args[3 ] = {llvm::ConstantExpr::getBitCast (FuncNameVar, I8PtrTy),
1234
1230
Builder.getInt64 (FunctionHash),
1235
- Builder.getInt32 (RegionMCDCState->BitmapBytes )};
1231
+ Builder.getInt32 (RegionMCDCState->BitmapBits )};
1236
1232
Builder.CreateCall (
1237
1233
CGM.getIntrinsic (llvm::Intrinsic::instrprof_mcdc_parameters), Args);
1238
1234
}
@@ -1250,6 +1246,11 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1250
1246
if (DecisionStateIter == RegionMCDCState->DecisionByStmt .end ())
1251
1247
return ;
1252
1248
1249
+ // Don't create tvbitmap_update if the record is allocated but excluded.
1250
+ // Or `bitmap |= (1 << 0)` would be wrongly executed to the next bitmap.
1251
+ if (DecisionStateIter->second .Indices .size () == 0 )
1252
+ return ;
1253
+
1253
1254
// Extract the offset of the global bitmap associated with this expression.
1254
1255
unsigned MCDCTestVectorBitmapOffset = DecisionStateIter->second .BitmapIdx ;
1255
1256
auto *I8PtrTy = llvm::PointerType::getUnqual (CGM.getLLVMContext ());
@@ -1261,7 +1262,7 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1261
1262
// index represents an executed test vector.
1262
1263
llvm::Value *Args[5 ] = {llvm::ConstantExpr::getBitCast (FuncNameVar, I8PtrTy),
1263
1264
Builder.getInt64 (FunctionHash),
1264
- Builder.getInt32 (RegionMCDCState-> BitmapBytes ),
1265
+ Builder.getInt32 (0 ), // Unused
1265
1266
Builder.getInt32 (MCDCTestVectorBitmapOffset),
1266
1267
MCDCCondBitmapAddr.emitRawPointer (CGF)};
1267
1268
Builder.CreateCall (
@@ -1305,19 +1306,22 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
1305
1306
// Extract the ID of the condition we are setting in the bitmap.
1306
1307
const auto &Branch = BranchStateIter->second ;
1307
1308
assert (Branch.ID >= 0 && " Condition has no ID!" );
1309
+ assert (Branch.DecisionStmt );
1308
1310
1309
- auto *I8PtrTy = llvm::PointerType::getUnqual (CGM.getLLVMContext ());
1311
+ // Cancel the emission if the Decision is erased after the allocation.
1312
+ const auto DecisionIter =
1313
+ RegionMCDCState->DecisionByStmt .find (Branch.DecisionStmt );
1314
+ if (DecisionIter == RegionMCDCState->DecisionByStmt .end ())
1315
+ return ;
1310
1316
1311
- // Emit intrinsic that updates a dedicated temporary value on the stack after
1312
- // a condition is evaluated. After the set of conditions has been updated,
1313
- // the resulting value is used to update the boolean expression's bitmap.
1314
- llvm::Value *Args[5 ] = {llvm::ConstantExpr::getBitCast (FuncNameVar, I8PtrTy),
1315
- Builder.getInt64 (FunctionHash),
1316
- Builder.getInt32 (Branch.ID ),
1317
- MCDCCondBitmapAddr.emitRawPointer (CGF), Val};
1318
- Builder.CreateCall (
1319
- CGM.getIntrinsic (llvm::Intrinsic::instrprof_mcdc_condbitmap_update),
1320
- Args);
1317
+ const auto &TVIdxs = DecisionIter->second .Indices [Branch.ID ];
1318
+
1319
+ auto *CurTV = Builder.CreateLoad (MCDCCondBitmapAddr,
1320
+ " mcdc." + Twine (Branch.ID + 1 ) + " .cur" );
1321
+ auto *NewTV = Builder.CreateAdd (CurTV, Builder.getInt32 (TVIdxs[true ]));
1322
+ NewTV = Builder.CreateSelect (
1323
+ Val, NewTV, Builder.CreateAdd (CurTV, Builder.getInt32 (TVIdxs[false ])));
1324
+ Builder.CreateStore (NewTV, MCDCCondBitmapAddr);
1321
1325
}
1322
1326
1323
1327
void CodeGenPGO::setValueProfilingFlag (llvm::Module &M) {
0 commit comments