InstrProfOptions Options;
Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
+
+ // TODO: Surface the option to emit atomic profile counter increments at
+ // the driver level.
+ Options.Atomic = LangOpts.Sanitize.has(SanitizerKind::Thread);
+
MPM.add(createInstrProfilingLegacyPass(Options));
}
if (CodeGenOpts.hasProfileIRInstr()) {
// is usually smaller than 2.
cl::init(1.0));
+cl::opt<bool> AtomicCounterUpdateAll(
+ "instrprof-atomic-counter-update-all", cl::ZeroOrMore,
+ cl::desc("Make all profile counter updates atomic (for testing only)"),
+ cl::init(false));
+
cl::opt<bool> AtomicCounterUpdatePromoted(
"atomic-counter-update-promoted", cl::ZeroOrMore,
cl::desc("Do counter update using atomic fetch add "
IRBuilder<> Builder(Inc);
uint64_t Index = Inc->getIndex()->getZExtValue();
Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index);
- Value *Load = Builder.CreateLoad(Addr, "pgocount");
- auto *Count = Builder.CreateAdd(Load, Inc->getStep());
- auto *Store = Builder.CreateStore(Count, Addr);
- Inc->replaceAllUsesWith(Store);
- if (isCounterPromotionEnabled())
- PromotionCandidates.emplace_back(cast<Instruction>(Load), Store);
+
+ if (Options.Atomic || AtomicCounterUpdateAll) {
+ Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, Inc->getStep(),
+ AtomicOrdering::Monotonic);
+ } else {
+ Value *Load = Builder.CreateLoad(Addr, "pgocount");
+ auto *Count = Builder.CreateAdd(Load, Inc->getStep());
+ auto *Store = Builder.CreateStore(Count, Addr);
+ if (isCounterPromotionEnabled())
+ PromotionCandidates.emplace_back(cast<Instruction>(Load), Store);
+ }
Inc->eraseFromParent();
}
--- /dev/null
+; RUN: opt < %s -S -instrprof -instrprof-atomic-counter-update-all | FileCheck %s
+
+target triple = "x86_64-apple-macosx10.10.0"
+
+@__profn_foo = hidden constant [3 x i8] c"foo"
+
+; CHECK-LABEL: define void @foo
+; CHECK-NEXT: atomicrmw add i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0), i64 1 monotonic
+define void @foo() {
+ call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__profn_foo, i32 0, i32 0), i64 0, i32 1, i32 0)
+ ret void
+}
+
+declare void @llvm.instrprof.increment(i8*, i64, i32, i32)