@@ -167,6 +167,8 @@ 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;
170
172
// / The state of MC/DC Coverage in this function.
171
173
MCDC::State &MCDCState;
172
174
// / Maximum number of supported MC/DC conditions in a boolean expression.
@@ -181,7 +183,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
181
183
MCDC::State &MCDCState, unsigned MCDCMaxCond,
182
184
DiagnosticsEngine &Diag)
183
185
: NextCounter(0 ), Hash(HashVersion), CounterMap(CounterMap),
184
- MCDCState (MCDCState), MCDCMaxCond(MCDCMaxCond),
186
+ NextMCDCBitmapIdx ( 0 ), MCDCState(MCDCState), MCDCMaxCond(MCDCMaxCond),
185
187
ProfileVersion(ProfileVersion), Diag(Diag) {}
186
188
187
189
// Blocks and lambdas are handled as separate functions, so we need not
@@ -312,8 +314,11 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
312
314
return true ;
313
315
}
314
316
315
- // Otherwise, allocate the Decision.
316
- MCDCState.DecisionByStmt [BinOp].BitmapIdx = 0 ;
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;
317
322
}
318
323
return true ;
319
324
}
@@ -1078,9 +1083,7 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) {
1078
1083
// for most embedded applications. Setting a maximum value prevents the
1079
1084
// bitmap footprint from growing too large without the user's knowledge. In
1080
1085
// the future, this value could be adjusted with a command-line option.
1081
- unsigned MCDCMaxConditions =
1082
- (CGM.getCodeGenOpts ().MCDCCoverage ? CGM.getCodeGenOpts ().MCDCMaxConds
1083
- : 0 );
1086
+ unsigned MCDCMaxConditions = (CGM.getCodeGenOpts ().MCDCCoverage ) ? 6 : 0 ;
1084
1087
1085
1088
RegionCounterMap.reset (new llvm::DenseMap<const Stmt *, unsigned >);
1086
1089
RegionMCDCState.reset (new MCDC::State);
@@ -1096,6 +1099,7 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) {
1096
1099
Walker.TraverseDecl (const_cast <CapturedDecl *>(CD));
1097
1100
assert (Walker.NextCounter > 0 && " no entry counter mapped for decl" );
1098
1101
NumRegionCounters = Walker.NextCounter ;
1102
+ RegionMCDCState->BitmapBytes = Walker.NextMCDCBitmapIdx ;
1099
1103
FunctionHash = Walker.Hash .finalize ();
1100
1104
}
1101
1105
@@ -1228,7 +1232,7 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
1228
1232
// anything.
1229
1233
llvm::Value *Args[3 ] = {llvm::ConstantExpr::getBitCast (FuncNameVar, I8PtrTy),
1230
1234
Builder.getInt64 (FunctionHash),
1231
- Builder.getInt32 (RegionMCDCState->BitmapBits )};
1235
+ Builder.getInt32 (RegionMCDCState->BitmapBytes )};
1232
1236
Builder.CreateCall (
1233
1237
CGM.getIntrinsic (llvm::Intrinsic::instrprof_mcdc_parameters), Args);
1234
1238
}
@@ -1246,11 +1250,6 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1246
1250
if (DecisionStateIter == RegionMCDCState->DecisionByStmt .end ())
1247
1251
return ;
1248
1252
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
-
1254
1253
// Extract the offset of the global bitmap associated with this expression.
1255
1254
unsigned MCDCTestVectorBitmapOffset = DecisionStateIter->second .BitmapIdx ;
1256
1255
auto *I8PtrTy = llvm::PointerType::getUnqual (CGM.getLLVMContext ());
@@ -1262,7 +1261,7 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
1262
1261
// index represents an executed test vector.
1263
1262
llvm::Value *Args[5 ] = {llvm::ConstantExpr::getBitCast (FuncNameVar, I8PtrTy),
1264
1263
Builder.getInt64 (FunctionHash),
1265
- Builder.getInt32 (0 ), // Unused
1264
+ Builder.getInt32 (RegionMCDCState-> BitmapBytes ),
1266
1265
Builder.getInt32 (MCDCTestVectorBitmapOffset),
1267
1266
MCDCCondBitmapAddr.emitRawPointer (CGF)};
1268
1267
Builder.CreateCall (
@@ -1306,22 +1305,19 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
1306
1305
// Extract the ID of the condition we are setting in the bitmap.
1307
1306
const auto &Branch = BranchStateIter->second ;
1308
1307
assert (Branch.ID >= 0 && " Condition has no ID!" );
1309
- assert (Branch.DecisionStmt );
1310
-
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 ;
1316
1308
1317
- const auto &TVIdxs = DecisionIter-> second . Indices [Branch. ID ] ;
1309
+ auto *I8PtrTy = llvm::PointerType::getUnqual (CGM. getLLVMContext ()) ;
1318
1310
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);
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);
1325
1321
}
1326
1322
1327
1323
void CodeGenPGO::setValueProfilingFlag (llvm::Module &M) {
0 commit comments