void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
GlobalVariable *Counters = getOrCreateRegionCounters(Inc);
- IRBuilder<> Builder(Inc->getParent(), *Inc);
+ IRBuilder<> Builder(Inc);
uint64_t Index = Inc->getIndex()->getZExtValue();
Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index);
Value *Count = Builder.CreateLoad(Addr, "pgocount");
if (It != RegionCounters.end())
return It->second;
- // Move the name variable to the right section. Make sure it is placed in the
- // same comdat as its associated function. Otherwise, we may get multiple
- // counters for the same function in certain cases.
+ // Move the name variable to the right section. Place them in a COMDAT group
+ // if the associated function is a COMDAT. This will make sure that
+ // only one copy of counters of the COMDAT function will be emitted after
+ // linking.
Function *Fn = Inc->getParent()->getParent();
+ Comdat *ProfileVarsComdat = nullptr;
+ if (Fn->hasComdat())
+ ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars")));
Name->setSection(getNameSection());
Name->setAlignment(1);
- Name->setComdat(Fn->getComdat());
+ Name->setComdat(ProfileVarsComdat);
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
LLVMContext &Ctx = M->getContext();
Counters->setVisibility(Name->getVisibility());
Counters->setSection(getCountersSection());
Counters->setAlignment(8);
- Counters->setComdat(Fn->getComdat());
+ Counters->setComdat(ProfileVarsComdat);
RegionCounters[Inc->getName()] = Counters;
Data->setVisibility(Name->getVisibility());
Data->setSection(getDataSection());
Data->setAlignment(8);
- Data->setComdat(Fn->getComdat());
+ Data->setComdat(ProfileVarsComdat);
// Mark the data variable as used so that it isn't stripped out.
UsedVars.push_back(Data);
if (Triple(M->getTargetTriple()).isOSDarwin())
return;
+ // Use linker script magic to get data/cnts/name start/end.
+ if (Triple(M->getTargetTriple()).isOSLinux() ||
+ Triple(M->getTargetTriple()).isOSFreeBSD())
+ return;
+
// Construct the function.
auto *VoidTy = Type::getVoidTy(M->getContext());
auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext());
Function::Create(SetNameTy, GlobalValue::ExternalLinkage,
"__llvm_profile_override_default_filename", M);
- // Create variable for profile name
+ // Create variable for profile name.
Constant *ProfileNameConst =
ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
GlobalVariable *ProfileName =