[PATCH] D69740: [profile] Support counter relocation at runtime

2022-04-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.
Herald added subscribers: abrachet, MaskRay.
Herald added a project: All.



Comment at: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp:673
+auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), LI);
+Addr = Builder.CreateIntToPtr(Add, Int64PtrTy);
+  }

It looks like this may be creating invalid IR in some cases: 
https://github.com/llvm/llvm-project/issues/55125


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69740: [profile] Support counter relocation at runtime

2020-01-17 Thread Petr Hosek via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd3db13af7e5c: [profile] Support counter relocation at 
runtime (authored by phosek).

Changed prior to commit:
  https://reviews.llvm.org/D69740?vs=238689=238901#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740

Files:
  clang/docs/SourceBasedCodeCoverage.rst
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/CMakeLists.txt
  compiler-rt/lib/profile/InstrProfiling.h
  compiler-rt/lib/profile/InstrProfilingBiasVar.c
  compiler-rt/lib/profile/InstrProfilingBuffer.c
  compiler-rt/lib/profile/InstrProfilingFile.c
  compiler-rt/lib/profile/InstrProfilingInternal.h
  compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c
  compiler-rt/test/profile/ContinuousSyncMode/basic.c
  compiler-rt/test/profile/ContinuousSyncMode/lit.local.cfg.py
  compiler-rt/test/profile/ContinuousSyncMode/multiple-DSOs.c
  compiler-rt/test/profile/ContinuousSyncMode/online-merging.c
  compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c
  compiler-rt/test/profile/ContinuousSyncMode/runtime-counter-relocation.c
  compiler-rt/test/profile/ContinuousSyncMode/set-file-object.c
  compiler-rt/test/profile/ContinuousSyncMode/set-filename.c
  llvm/include/llvm/ProfileData/InstrProf.h
  llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
  llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
  llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll

Index: llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -S -instrprof | FileCheck %s
+; RUN: opt < %s -S -instrprof -runtime-counter-relocation | FileCheck -check-prefixes=RELOC %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@__profn_foo = hidden constant [3 x i8] c"foo"
+; RELOC: @__llvm_profile_counter_bias = linkonce_odr global i64 0
+
+; CHECK-LABEL: define void @foo
+; CHECK-NEXT: %pgocount = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; CHECK-NEXT: %1 = add i64 %pgocount, 1
+; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; RELOC-LABEL: define void @foo
+; RELOC-NEXT: %1 = load i64, i64* @__llvm_profile_counter_bias
+; RELOC-NEXT: %2 = add i64 ptrtoint ([1 x i64]* @__profc_foo to i64), %1
+; RELOC-NEXT: %3 = inttoptr i64 %2 to i64*
+; RELOC-NEXT: %pgocount = load i64, i64* %3
+; RELOC-NEXT: %4 = add i64 %pgocount, 1
+; RELOC-NEXT: store i64 %4, i64* %3
+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)
Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -83,6 +83,11 @@
 cl::desc("Rename counter variable of a comdat function based on cfg hash"),
 cl::init(true));
 
+cl::opt RuntimeCounterRelocation(
+"runtime-counter-relocation",
+cl::desc("Enable relocating counters at runtime."),
+cl::init(false));
+
 cl::opt ValueProfileStaticAlloc(
 "vp-static-alloc",
 cl::desc("Do static counter allocation for value profiler"),
@@ -431,6 +436,13 @@
   return true;
 }
 
+bool InstrProfiling::isRuntimeCounterRelocationEnabled() const {
+  if (RuntimeCounterRelocation.getNumOccurrences() > 0)
+return RuntimeCounterRelocation;
+
+  return TT.isOSFuchsia();
+}
+
 bool InstrProfiling::isCounterPromotionEnabled() const {
   if (DoCounterPromotion.getNumOccurrences() > 0)
 return DoCounterPromotion;
@@ -641,6 +653,26 @@
   Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(),
Counters, 0, Index);
 
+  if (isRuntimeCounterRelocationEnabled()) {
+Type *Int64Ty = Type::getInt64Ty(M->getContext());
+Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext());
+Function *Fn = Inc->getParent()->getParent();
+Instruction  = Fn->getEntryBlock().front();
+LoadInst *LI = dyn_cast();
+if (!LI) {
+  IRBuilder<> Builder();
+  Type *Int64Ty = Type::getInt64Ty(M->getContext());
+  GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
+  if (!Bias)
+Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
+  Constant::getNullValue(Int64Ty),
+  getInstrProfCounterBiasVarName());
+  LI = Builder.CreateLoad(Int64Ty, Bias);
+}
+auto 

[PATCH] D69740: [profile] Support counter relocation at runtime

2020-01-16 Thread Petr Hosek via Phabricator via cfe-commits
phosek updated this revision to Diff 238689.
phosek marked an inline comment as done.
phosek added a comment.

Addressed the comment and also added a test for Linux.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740

Files:
  clang/docs/SourceBasedCodeCoverage.rst
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/CMakeLists.txt
  compiler-rt/lib/profile/InstrProfiling.h
  compiler-rt/lib/profile/InstrProfilingBiasVar.c
  compiler-rt/lib/profile/InstrProfilingBuffer.c
  compiler-rt/lib/profile/InstrProfilingFile.c
  compiler-rt/lib/profile/InstrProfilingInternal.h
  compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c
  compiler-rt/test/profile/ContinuousSyncMode/basic.c
  compiler-rt/test/profile/ContinuousSyncMode/lit.local.cfg.py
  compiler-rt/test/profile/ContinuousSyncMode/multiple-DSOs.c
  compiler-rt/test/profile/ContinuousSyncMode/online-merging.c
  compiler-rt/test/profile/ContinuousSyncMode/pid-substitution.c
  compiler-rt/test/profile/ContinuousSyncMode/runtime-counter-relocation.c
  compiler-rt/test/profile/ContinuousSyncMode/set-file-object.c
  compiler-rt/test/profile/ContinuousSyncMode/set-filename.c
  llvm/include/llvm/ProfileData/InstrProf.h
  llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
  llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
  llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll

Index: llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -S -instrprof | FileCheck %s
+; RUN: opt < %s -S -instrprof -runtime-counter-relocation | FileCheck -check-prefixes=RELOC %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@__profn_foo = hidden constant [3 x i8] c"foo"
+; RELOC: @__llvm_profile_counter_bias = linkonce_odr global i64 0
+
+; CHECK-LABEL: define void @foo
+; CHECK-NEXT: %pgocount = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; CHECK-NEXT: %1 = add i64 %pgocount, 1
+; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; RELOC-LABEL: define void @foo
+; RELOC-NEXT: %1 = load i64, i64* @__llvm_profile_counter_bias
+; RELOC-NEXT: %2 = add i64 ptrtoint ([1 x i64]* @__profc_foo to i64), %1
+; RELOC-NEXT: %3 = inttoptr i64 %2 to i64*
+; RELOC-NEXT: %pgocount = load i64, i64* %3
+; RELOC-NEXT: %4 = add i64 %pgocount, 1
+; RELOC-NEXT: store i64 %4, i64* %3
+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)
Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -83,6 +83,11 @@
 cl::desc("Rename counter variable of a comdat function based on cfg hash"),
 cl::init(true));
 
+cl::opt RuntimeCounterRelocation(
+"runtime-counter-relocation",
+cl::desc("Enable relocating counters at runtime."),
+cl::init(false));
+
 cl::opt ValueProfileStaticAlloc(
 "vp-static-alloc",
 cl::desc("Do static counter allocation for value profiler"),
@@ -431,6 +436,13 @@
   return true;
 }
 
+bool InstrProfiling::isRuntimeCounterRelocationEnabled() const {
+  if (RuntimeCounterRelocation.getNumOccurrences() > 0)
+return RuntimeCounterRelocation;
+
+  return TT.isOSFuchsia();
+}
+
 bool InstrProfiling::isCounterPromotionEnabled() const {
   if (DoCounterPromotion.getNumOccurrences() > 0)
 return DoCounterPromotion;
@@ -641,6 +653,26 @@
   Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(),
Counters, 0, Index);
 
+  if (isRuntimeCounterRelocationEnabled()) {
+Type *Int64Ty = Type::getInt64Ty(M->getContext());
+Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext());
+Function *Fn = Inc->getParent()->getParent();
+Instruction  = Fn->getEntryBlock().front();
+LoadInst *LI = dyn_cast();
+if (!LI) {
+  IRBuilder<> Builder();
+  Type *Int64Ty = Type::getInt64Ty(M->getContext());
+  GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
+  if (!Bias)
+Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
+  Constant::getNullValue(Int64Ty),
+  getInstrProfCounterBiasVarName());
+  LI = Builder.CreateLoad(Int64Ty, Bias);
+}
+auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), LI);
+Addr = 

[PATCH] D69740: [profile] Support counter relocation at runtime

2019-12-02 Thread Vedant Kumar via Phabricator via cfe-commits
vsk accepted this revision.
vsk added a comment.
This revision is now accepted and ready to land.

Lgtm with a small cleanup.




Comment at: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp:674
+  if (isRuntimeCounterRelocationEnabled()) {
+Type *Int64Ty = Type::getInt64Ty(M->getContext());
+Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext());

Could you lazily insert the bias load inside of `lowerIncrement`? That removes 
the need to delete the load when no increment is found.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69740: [profile] Support counter relocation at runtime

2019-11-22 Thread Petr Hosek via Phabricator via cfe-commits
phosek added a comment.

In D69740#1752348 , @vsk wrote:

> I think this looks good overall. The only high-level item that seems to be 
> missing is Fuchsia testing -- are there any bots for this?


Not yet unfortunately, it's something I'm slowly working on but it'll take more 
time. I've been only testing this manually for now.

> I've left inline comments about fixing up some tests. Please also leave a 
> comment about Fuchsia/-runtime-counter-relocation in 
> clang/docs/SourceBasedCodeCoverage.rst.

Done.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69740: [profile] Support counter relocation at runtime

2019-11-22 Thread Petr Hosek via Phabricator via cfe-commits
phosek updated this revision to Diff 230733.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740

Files:
  clang/docs/SourceBasedCodeCoverage.rst
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/CMakeLists.txt
  compiler-rt/lib/profile/InstrProfiling.h
  compiler-rt/lib/profile/InstrProfilingBiasVar.c
  compiler-rt/lib/profile/InstrProfilingBuffer.c
  compiler-rt/lib/profile/InstrProfilingFile.c
  compiler-rt/lib/profile/InstrProfilingInternal.h
  compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c
  llvm/include/llvm/ProfileData/InstrProf.h
  llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
  llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
  llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll

Index: llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -S -instrprof | FileCheck %s
+; RUN: opt < %s -S -instrprof -runtime-counter-relocation | FileCheck -check-prefixes=RELOC %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@__profn_foo = hidden constant [3 x i8] c"foo"
+; RELOC: @__llvm_profile_counter_bias = linkonce_odr global i64 0
+
+; CHECK-LABEL: define void @foo
+; CHECK-NEXT: %pgocount = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; CHECK-NEXT: %1 = add i64 %pgocount, 1
+; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; RELOC-LABEL: define void @foo
+; RELOC-NEXT: %1 = load i64, i64* @__llvm_profile_counter_bias
+; RELOC-NEXT: %2 = add i64 ptrtoint ([1 x i64]* @__profc_foo to i64), %1
+; RELOC-NEXT: %3 = inttoptr i64 %2 to i64*
+; RELOC-NEXT: %pgocount = load i64, i64* %3
+; RELOC-NEXT: %4 = add i64 %pgocount, 1
+; RELOC-NEXT: store i64 %4, i64* %3
+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)
Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -83,6 +83,11 @@
 cl::desc("Rename counter variable of a comdat function based on cfg hash"),
 cl::init(true));
 
+cl::opt RuntimeCounterRelocation(
+"runtime-counter-relocation",
+cl::desc("Enable relocating counters at runtime."),
+cl::init(false));
+
 cl::opt ValueProfileStaticAlloc(
 "vp-static-alloc",
 cl::desc("Do static counter allocation for value profiler"),
@@ -408,6 +413,20 @@
 }
 
 bool InstrProfiling::lowerIntrinsics(Function *F) {
+  Value *Load = nullptr;
+  if (isRuntimeCounterRelocationEnabled()) {
+if (!F->empty()) {
+  IRBuilder<> Builder(>getEntryBlock().front());
+  Type *Int64Ty = Type::getInt64Ty(M->getContext());
+  GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
+  if (!Bias)
+Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
+  Constant::getNullValue(Int64Ty),
+  getInstrProfCounterBiasVarName());
+  Load = Builder.CreateLoad(Int64Ty, Bias);
+}
+  }
+
   bool MadeChange = false;
   PromotionCandidates.clear();
   for (BasicBlock  : *F) {
@@ -424,13 +443,23 @@
 }
   }
 
-  if (!MadeChange)
+  if (!MadeChange) {
+if (RuntimeCounterRelocation && Load)
+  Load->deleteValue();
 return false;
+  }
 
   promoteCounterLoadStores(F);
   return true;
 }
 
+bool InstrProfiling::isRuntimeCounterRelocationEnabled() const {
+  if (RuntimeCounterRelocation.getNumOccurrences() > 0)
+return RuntimeCounterRelocation;
+
+  return TT.isOSFuchsia();
+}
+
 bool InstrProfiling::isCounterPromotionEnabled() const {
   if (DoCounterPromotion.getNumOccurrences() > 0)
 return DoCounterPromotion;
@@ -641,6 +670,17 @@
   Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(),
Counters, 0, Index);
 
+  if (isRuntimeCounterRelocationEnabled()) {
+Type *Int64Ty = Type::getInt64Ty(M->getContext());
+Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext());
+Function *Fn = Inc->getParent()->getParent();
+Instruction  = Fn->getEntryBlock().front();
+if (LoadInst *LI = dyn_cast()) {
+  auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), LI);
+  Addr = Builder.CreateIntToPtr(Add, Int64PtrTy);
+}
+  }
+
   if (Options.Atomic || AtomicCounterUpdateAll) {
 Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, 

[PATCH] D69740: [profile] Support counter relocation at runtime

2019-11-22 Thread Petr Hosek via Phabricator via cfe-commits
phosek updated this revision to Diff 230727.
phosek marked 2 inline comments as done.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69740/new/

https://reviews.llvm.org/D69740

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  compiler-rt/lib/profile/CMakeLists.txt
  compiler-rt/lib/profile/InstrProfiling.h
  compiler-rt/lib/profile/InstrProfilingBiasVar.c
  compiler-rt/lib/profile/InstrProfilingBuffer.c
  compiler-rt/lib/profile/InstrProfilingFile.c
  compiler-rt/lib/profile/InstrProfilingInternal.h
  compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c
  llvm/include/llvm/ProfileData/InstrProf.h
  llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
  llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
  llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll

Index: llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/InstrProfiling/runtime-counter-relocation.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -S -instrprof | FileCheck %s
+; RUN: opt < %s -S -instrprof -runtime-counter-relocation | FileCheck -check-prefixes=RELOC %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@__profn_foo = hidden constant [3 x i8] c"foo"
+; RELOC: @__llvm_profile_counter_bias = linkonce_odr global i64 0
+
+; CHECK-LABEL: define void @foo
+; CHECK-NEXT: %pgocount = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; CHECK-NEXT: %1 = add i64 %pgocount, 1
+; CHECK-NEXT: store i64 %1, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i64 0, i64 0)
+; RELOC-LABEL: define void @foo
+; RELOC-NEXT: %1 = load i64, i64* @__llvm_profile_counter_bias
+; RELOC-NEXT: %2 = add i64 ptrtoint ([1 x i64]* @__profc_foo to i64), %1
+; RELOC-NEXT: %3 = inttoptr i64 %2 to i64*
+; RELOC-NEXT: %pgocount = load i64, i64* %3
+; RELOC-NEXT: %4 = add i64 %pgocount, 1
+; RELOC-NEXT: store i64 %4, i64* %3
+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)
Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
===
--- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -83,6 +83,11 @@
 cl::desc("Rename counter variable of a comdat function based on cfg hash"),
 cl::init(true));
 
+cl::opt RuntimeCounterRelocation(
+"runtime-counter-relocation",
+cl::desc("Enable relocating counters at runtime."),
+cl::init(false));
+
 cl::opt ValueProfileStaticAlloc(
 "vp-static-alloc",
 cl::desc("Do static counter allocation for value profiler"),
@@ -408,6 +413,20 @@
 }
 
 bool InstrProfiling::lowerIntrinsics(Function *F) {
+  Value *Load = nullptr;
+  if (isRuntimeCounterRelocationEnabled()) {
+if (!F->empty()) {
+  IRBuilder<> Builder(>getEntryBlock().front());
+  Type *Int64Ty = Type::getInt64Ty(M->getContext());
+  GlobalVariable *Bias = M->getGlobalVariable(getInstrProfCounterBiasVarName());
+  if (!Bias)
+Bias = new GlobalVariable(*M, Int64Ty, false, GlobalValue::LinkOnceODRLinkage,
+  Constant::getNullValue(Int64Ty),
+  getInstrProfCounterBiasVarName());
+  Load = Builder.CreateLoad(Int64Ty, Bias);
+}
+  }
+
   bool MadeChange = false;
   PromotionCandidates.clear();
   for (BasicBlock  : *F) {
@@ -424,13 +443,23 @@
 }
   }
 
-  if (!MadeChange)
+  if (!MadeChange) {
+if (RuntimeCounterRelocation && Load)
+  Load->deleteValue();
 return false;
+  }
 
   promoteCounterLoadStores(F);
   return true;
 }
 
+bool InstrProfiling::isRuntimeCounterRelocationEnabled() const {
+  if (RuntimeCounterRelocation.getNumOccurrences() > 0)
+return RuntimeCounterRelocation;
+
+  return TT.isOSFuchsia();
+}
+
 bool InstrProfiling::isCounterPromotionEnabled() const {
   if (DoCounterPromotion.getNumOccurrences() > 0)
 return DoCounterPromotion;
@@ -641,6 +670,17 @@
   Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters->getValueType(),
Counters, 0, Index);
 
+  if (isRuntimeCounterRelocationEnabled()) {
+Type *Int64Ty = Type::getInt64Ty(M->getContext());
+Type *Int64PtrTy = Type::getInt64PtrTy(M->getContext());
+Function *Fn = Inc->getParent()->getParent();
+Instruction  = Fn->getEntryBlock().front();
+if (LoadInst *LI = dyn_cast()) {
+  auto *Add = Builder.CreateAdd(Builder.CreatePtrToInt(Addr, Int64Ty), LI);
+  Addr = Builder.CreateIntToPtr(Add, Int64PtrTy);
+}
+  }
+
   if (Options.Atomic ||