-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MC/DC][Coverage] Split out Read-modfy-Write to rmw_or(ptr,i8) #96040
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -237,6 +237,10 @@ class InstrLowerer final { | |
GlobalVariable *NamesVar = nullptr; | ||
size_t NamesSize = 0; | ||
|
||
/// The instance of [[forceinline]] rmw_or(ptr, i8). | ||
/// This is name-insensitive. | ||
Function *RMWOrFunc = nullptr; | ||
|
||
// vector of counter load/store pairs to be register promoted. | ||
std::vector<LoadStorePair> PromotionCandidates; | ||
|
||
|
@@ -297,6 +301,14 @@ class InstrLowerer final { | |
StringRef Name, | ||
GlobalValue::LinkageTypes Linkage); | ||
|
||
/// Create [[forceinline]] rmw_or(ptr, i8). | ||
/// This doesn't update `RMWOrFunc`. | ||
Function *createRMWOrFunc(); | ||
|
||
/// Get the call to `rmw_or`. | ||
/// Create the instance if it is unknown. | ||
CallInst *getRMWOrCall(Value *Addr, Value *Val); | ||
|
||
/// Compute the address of the test vector bitmap that this profiling | ||
/// instruction acts on. | ||
Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I); | ||
|
@@ -937,6 +949,44 @@ Value *InstrLowerer::getCounterAddress(InstrProfCntrInstBase *I) { | |
return Builder.CreateIntToPtr(Add, Addr->getType()); | ||
} | ||
|
||
Function *InstrLowerer::createRMWOrFunc() { | ||
auto &Ctx = M.getContext(); | ||
auto *Int8Ty = Type::getInt8Ty(Ctx); | ||
// void alwaysinline rmw_or(ptr, i8) | ||
Function *Fn = Function::Create( | ||
FunctionType::get(Type::getVoidTy(Ctx), | ||
{PointerType::getUnqual(Ctx), Int8Ty}, false), | ||
Function::LinkageTypes::PrivateLinkage, "rmw_or", M); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a convention for naming compiler-generated functions? Will there be problems if a user creates a function with the same name? Or is this ok becase the linkage is private? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose private named functions wouldn't clash. Let me reconfirm later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've reconfirmed this won't clash. If I called This may work with unnamed. |
||
Fn->addFnAttr(Attribute::AlwaysInline); | ||
auto *ArgAddr = Fn->getArg(0); | ||
auto *ArgVal = Fn->getArg(1); | ||
IRBuilder<> Builder(BasicBlock::Create(Ctx, "", Fn)); | ||
|
||
// Load profile bitmap byte. | ||
// %mcdc.bits = load i8, ptr %4, align 1 | ||
auto *Bitmap = Builder.CreateLoad(Int8Ty, ArgAddr, "mcdc.bits"); | ||
|
||
// Perform logical OR of profile bitmap byte and shifted bit offset. | ||
// %8 = or i8 %mcdc.bits, %7 | ||
auto *Result = Builder.CreateOr(Bitmap, ArgVal); | ||
|
||
// Store the updated profile bitmap byte. | ||
// store i8 %8, ptr %3, align 1 | ||
Builder.CreateStore(Result, ArgAddr); | ||
|
||
// Terminator | ||
Builder.CreateRetVoid(); | ||
|
||
return Fn; | ||
} | ||
|
||
CallInst *InstrLowerer::getRMWOrCall(Value *Addr, Value *Val) { | ||
if (!RMWOrFunc) | ||
RMWOrFunc = createRMWOrFunc(); | ||
|
||
return CallInst::Create(RMWOrFunc, {Addr, Val}); | ||
} | ||
|
||
Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) { | ||
auto *Bitmaps = getOrCreateRegionBitmaps(I); | ||
IRBuilder<> Builder(I); | ||
|
@@ -1044,17 +1094,7 @@ void InstrLowerer::lowerMCDCTestVectorBitmapUpdate( | |
// %7 = shl i8 1, %6 | ||
auto *ShiftedVal = Builder.CreateShl(Builder.getInt8(0x1), BitToSet); | ||
|
||
// Load profile bitmap byte. | ||
// %mcdc.bits = load i8, ptr %4, align 1 | ||
auto *Bitmap = Builder.CreateLoad(Int8Ty, BitmapByteAddr, "mcdc.bits"); | ||
|
||
// Perform logical OR of profile bitmap byte and shifted bit offset. | ||
// %8 = or i8 %mcdc.bits, %7 | ||
auto *Result = Builder.CreateOr(Bitmap, ShiftedVal); | ||
|
||
// Store the updated profile bitmap byte. | ||
// store i8 %8, ptr %3, align 1 | ||
Builder.CreateStore(Result, BitmapByteAddr); | ||
Builder.Insert(getRMWOrCall(BitmapByteAddr, ShiftedVal)); | ||
Update->eraseFromParent(); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document this function with basic C code to make is easy to understand what it's doing.