bridge: mark write barrier functions GC leaf

Set "gc-leaf-function" attribute for the write barrier
functions. The backend understands this attribute and does not
treats the call sites as statepoints.
(llvm/lib/Transforms/Utils/Local.cpp, callsGCLeafFunction)
This makes the write barriers cheaper (avoid spillings), and
also makes it easier to remove write barriers for stack writes
(not in this CL).

Change-Id: Id5b97275b99c8717d3b9c095231ee0f6e09fe00c
Reviewed-on: https://go-review.googlesource.com/c/156558
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 41eaa0c..963c042 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -2533,6 +2533,25 @@
   return errorFunction_.get();
 }
 
+// This is a list of functions the call sites of which are not
+// GC statepoints.
+//
+// Keep this sync with the runtime and the frontend.
+static std::string gcleaffuncs[] = {
+  "runtime.gcWriteBarrier",
+  "runtime.typedmemmove",
+};
+
+static bool isGCLeaf(std::string name)
+{
+
+  for (auto f : gcleaffuncs)
+    if (name == f)
+      return true;
+  return false;
+
+}
+
 // Declare or define a new function.
 
 Bfunction *Llvm_backend::function(Btype *fntype, const std::string &name,
@@ -2616,6 +2635,10 @@
     fcn->addFnAttr("target-cpu", targetCpuAttr_);
     fcn->addFnAttr("target-features", targetFeaturesAttr_);
 
+    // attribute for GC leaf function (i.e. not a statepoint)
+    if (isGCLeaf(fns))
+      fcn->addFnAttr("gc-leaf-function");
+
     fcnValue = fcn;
 
     // Fix up references to declaration of old type.