Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1671,9 +1671,6 @@ class CodeGenFunction : public CodeGenTypeCache {

CodeGenPGO PGO;

/// Bitmap used by MC/DC to track condition outcomes of a boolean expression.
Address MCDCCondBitmapAddr = Address::invalid();

/// Calculate branch weights appropriate for PGO data
llvm::MDNode *createProfileWeights(uint64_t TrueCount,
uint64_t FalseCount) const;
Expand Down Expand Up @@ -1712,8 +1709,12 @@ class CodeGenFunction : public CodeGenTypeCache {
void maybeCreateMCDCCondBitmap() {
if (isMCDCCoverageEnabled()) {
PGO.emitMCDCParameters(Builder);
MCDCCondBitmapAddr =
CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");

// Set up MCDCCondBitmapAddr for each Decision.
// Note: This doesn't initialize Addrs in invalidated Decisions.
for (auto *MCDCCondBitmapAddr : PGO.getMCDCCondBitmapAddrArray(Builder))
*MCDCCondBitmapAddr =
CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
}
}

Expand All @@ -1725,7 +1726,7 @@ class CodeGenFunction : public CodeGenTypeCache {
/// Zero-init the MCDC temp value.
void maybeResetMCDCCondBitmap(const Expr *E) {
if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
PGO.emitMCDCCondBitmapReset(Builder, E);
PGO.setCurrentStmt(E);
}
}
Expand All @@ -1734,15 +1735,15 @@ class CodeGenFunction : public CodeGenTypeCache {
/// If \p StepV is null, the default increment is 1.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E) {
if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this);
PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, *this);
PGO.setCurrentStmt(E);
}
}

/// Update the MCDC temp value with the condition's evaluated result.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) {
if (isMCDCCoverageEnabled()) {
PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this);
PGO.emitMCDCCondBitmapUpdate(Builder, E, Val, *this);
PGO.setCurrentStmt(E);
}
}
Expand Down
41 changes: 35 additions & 6 deletions clang/lib/CodeGen/CodeGenPGO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1245,9 +1245,29 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) {
CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_parameters), Args);
}

/// Fill mcdc.addr order by ID.
std::vector<Address *>
CodeGenPGO::getMCDCCondBitmapAddrArray(CGBuilderTy &Builder) {
std::vector<Address *> Result;

if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we ever call this function if canEmitMCDCCoverage is false?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that many parts of the code already follow this pattern. Therefore, I think I'm fine with this for now. I think it should be cleaned up eventually though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look in the future. Please be patient. :)

return Result;

SmallVector<std::pair<unsigned, Address *>> SortedPair;
for (auto &[_, V] : RegionMCDCState->DecisionByStmt)
if (V.isValid())
SortedPair.emplace_back(V.ID, &V.MCDCCondBitmapAddr);

llvm::sort(SortedPair);

for (auto &[_, MCDCCondBitmapAddr] : SortedPair)
Result.push_back(MCDCCondBitmapAddr);

return Result;
}

void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
const Expr *S,
Address MCDCCondBitmapAddr,
CodeGenFunction &CGF) {
if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
return;
Expand All @@ -1258,6 +1278,10 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
if (DecisionStateIter == RegionMCDCState->DecisionByStmt.end())
return;

auto &MCDCCondBitmapAddr = DecisionStateIter->second.MCDCCondBitmapAddr;
if (!MCDCCondBitmapAddr.isValid())
return;

// Don't create tvbitmap_update if the record is allocated but excluded.
// Or `bitmap |= (1 << 0)` would be wrongly executed to the next bitmap.
if (DecisionStateIter->second.Indices.size() == 0)
Expand All @@ -1280,22 +1304,23 @@ void CodeGenPGO::emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder,
CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_tvbitmap_update), Args);
}

void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr) {
void CodeGenPGO::emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S) {
if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
return;

S = S->IgnoreParens();
auto I = RegionMCDCState->DecisionByStmt.find(S->IgnoreParens());
if (I == RegionMCDCState->DecisionByStmt.end())
return;

if (!RegionMCDCState->DecisionByStmt.contains(S))
auto &MCDCCondBitmapAddr = I->second.MCDCCondBitmapAddr;
if (!MCDCCondBitmapAddr.isValid())
return;

// Emit intrinsic that resets a dedicated temporary value on the stack to 0.
Builder.CreateStore(Builder.getInt32(0), MCDCCondBitmapAddr);
}

void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr,
llvm::Value *Val,
CodeGenFunction &CGF) {
if (!canEmitMCDCCoverage(Builder) || !RegionMCDCState)
Expand Down Expand Up @@ -1325,6 +1350,10 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
if (DecisionIter == RegionMCDCState->DecisionByStmt.end())
return;

auto &MCDCCondBitmapAddr = DecisionIter->second.MCDCCondBitmapAddr;
if (!MCDCCondBitmapAddr.isValid())
return;

const auto &TVIdxs = DecisionIter->second.Indices[Branch.ID];

auto *CurTV = Builder.CreateLoad(MCDCCondBitmapAddr,
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/CodeGen/CodeGenPGO.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,12 @@ class CodeGenPGO {
void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
llvm::Value *StepV);
void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr,
CodeGenFunction &CGF);
void emitMCDCParameters(CGBuilderTy &Builder);
void emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr);
std::vector<Address *> getMCDCCondBitmapAddrArray(CGBuilderTy &Builder);
void emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S);
void emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr, llvm::Value *Val,
CodeGenFunction &CGF);
llvm::Value *Val, CodeGenFunction &CGF);

void markStmtAsUsed(bool Skipped, const Stmt *S) {
// Do nothing.
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/MCDCState.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_LIB_CODEGEN_MCDCSTATE_H
#define LLVM_CLANG_LIB_CODEGEN_MCDCSTATE_H

#include "Address.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ProfileData/Coverage/MCDCTypes.h"
Expand All @@ -38,6 +39,7 @@ struct State {
unsigned BitmapIdx;
IndicesTy Indices;
unsigned ID = InvalidID;
Address MCDCCondBitmapAddr = Address::invalid();

bool isValid() const { return ID != InvalidID; }

Expand Down
18 changes: 10 additions & 8 deletions clang/test/Profile/c-mcdc-logicalop-ternary.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ int test(int a, int b, int c, int d, int e, int f) {

// ALLOCATE MCDC TEMP AND ZERO IT.
// MCDC-LABEL: @test(
// MCDC: %mcdc.addr = alloca i32, align 4
// MCDC: store i32 0, ptr %mcdc.addr, align 4
// MCDC: %[[ADDR0:mcdc.+]] = alloca i32, align 4
// MCDC: %[[ADDR1:mcdc.+]] = alloca i32, align 4
// MCDC: %[[ADDR2:mcdc.+]] = alloca i32, align 4
// MCDC: store i32 0, ptr %[[ADDR0]], align 4

// TERNARY TRUE SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 0.
// MCDC-LABEL: cond.true:
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %[[ADDR0]], align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
Expand All @@ -30,12 +32,12 @@ int test(int a, int b, int c, int d, int e, int f) {
// MCDC: store i8 %[[LAB9]], ptr %[[LAB4]], align 1

// CHECK FOR ZERO OF MCDC TEMP
// MCDC: store i32 0, ptr %mcdc.addr, align 4
// MCDC: store i32 0, ptr %[[ADDR1]], align 4

// TERNARY TRUE YIELDS TERNARY LHS LOGICAL-AND.
// TERNARY LHS LOGICAL-AND SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 1.
// MCDC-LABEL: land.end:
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %[[ADDR1]], align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 3
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
Expand All @@ -48,7 +50,7 @@ int test(int a, int b, int c, int d, int e, int f) {

// TERNARY FALSE SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 0.
// MCDC-LABEL: cond.false:
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.+]] = load i32, ptr %[[ADDR0]], align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
Expand All @@ -60,12 +62,12 @@ int test(int a, int b, int c, int d, int e, int f) {
// MCDC: store i8 %[[LAB9]], ptr %[[LAB4]], align 1

// CHECK FOR ZERO OF MCDC TEMP
// MCDC: store i32 0, ptr %mcdc.addr, align 4
// MCDC: store i32 0, ptr %[[ADDR2]], align 4

// TERNARY FALSE YIELDS TERNARY RHS LOGICAL-OR.
// TERNARY RHS LOGICAL-OR SHOULD UPDATE THE BITMAP WITH RESULT AT ELEMENT 2.
// MCDC-LABEL: lor.end:
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %mcdc.addr, align 4
// MCDC-DAG: %[[TEMP0:mcdc.temp[0-9]*]] = load i32, ptr %[[ADDR2]], align 4
// MCDC: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 6
// MCDC: %[[LAB1:[0-9]+]] = lshr i32 %[[TEMP]], 3
// MCDC: %[[LAB4:[0-9]+]] = getelementptr inbounds i8, ptr @__profbm_test, i32 %[[LAB1]]
Expand Down