gollvm: sync up with recent change to Backend::function

Adapt code to new Backend::function, which uses flag bits instead
of interface booleans for various function properties (see
https://go-review.googlesource.com/c/gofrontend/+/145319).

Change-Id: I1d4978b86d388ea3ad23b95e2a9301a47f49b302
Reviewed-on: https://go-review.googlesource.com/c/145597
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 6f0c34e..a13a74d 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -466,17 +466,12 @@
   // FIXME: may want to revisit these settings at some point. For example,
   // do we want to mark builtins as no-split-stack? Also it might be useful
   // to allow for creation of no-return builtins (such as longjmp, perhaps).
-  bool is_visible = true;
-  bool is_declaration = false;
-  bool is_inl = true;
-  bool is_splitstack = useSplitStack_;
-  bool in_unique_section = false;
-  bool is_noret = false;
+  unsigned flags = (Backend::function_is_visible |
+                    Backend::function_is_inlinable |
+                    (!useSplitStack_ ? Backend::function_no_split_stack : 0));
 
   // Create function
-  return function(fcnType, be->name(), be->name(),
-                  is_visible, is_declaration, is_inl, is_splitstack,
-                  is_noret, in_unique_section, bloc);
+  return function(fcnType, be->name(), be->name(), flags, bloc);
 }
 
 bool Llvm_backend::moduleScopeValue(llvm::Value *val, Btype *btype) const
@@ -2512,10 +2507,8 @@
 // Declare or define a new function.
 
 Bfunction *Llvm_backend::function(Btype *fntype, const std::string &name,
-                                  const std::string &asm_name, bool is_visible,
-                                  bool is_declaration, bool is_inlinable,
-                                  bool disable_split_stack, bool no_return,
-                                  bool in_unique_section, Location location)
+                                  const std::string &asm_name, unsigned flags,
+                                  Location location)
 {
   if (fntype == errorType())
     return errorFunction_.get();
@@ -2527,7 +2520,7 @@
   // function with the same name, and reuse that if need be. Check to make
   // sure that the function types agree if we see a hit in the cache.
   std::string fns(!asm_name.empty() ? asm_name : name);
-  if (is_declaration) {
+  if ((flags & Backend::function_is_declaration) != 0) {
     assert(ft);
     fcnNameAndType candidate(std::make_pair(ft, fns));
     auto it = fcnDeclMap_.find(candidate);
@@ -2537,15 +2530,17 @@
     }
   }
 
-  llvm::GlobalValue::LinkageTypes linkage = is_visible ?
+  llvm::GlobalValue::LinkageTypes linkage =
+      ((flags & Backend::function_is_visible) != 0) ?
       llvm::GlobalValue::ExternalLinkage : llvm::GlobalValue::InternalLinkage;
   llvm::StringRef fn(fns);
   llvm::Constant *fcnValue = nullptr;
   llvm::Value *declVal = module_->getNamedValue(fn);
-  if (!is_declaration || !declVal) {
+  if (((flags & Backend::function_is_declaration) == 0) || !declVal) {
     llvm::Function *declFnVal = nullptr;
     llvm::FunctionType *declFnTyp;
-    if (!is_declaration && declVal && llvm::isa<llvm::Function>(declVal)) {
+    if (((flags & Backend::function_is_declaration) == 0) && declVal &&
+        llvm::isa<llvm::Function>(declVal)) {
       declFnVal = llvm::cast<llvm::Function>(declVal);
       declFnTyp = declFnVal->getFunctionType();
       if (declFnTyp == fty) {
@@ -2567,18 +2562,18 @@
     fcn->addFnAttr("disable-tail-calls", "true");
 
     // inline/noinline
-    if (!is_inlinable || noInline_)
+    if ((flags & Backend::function_is_inlinable) == 0 || noInline_)
       fcn->addFnAttr(llvm::Attribute::NoInline);
 
     // split-stack or nosplit
-    if (useSplitStack_ && !disable_split_stack)
+    if (useSplitStack_ && (flags & Backend::function_no_split_stack) == 0)
       fcn->addFnAttr("split-stack");
 
     // allow elim frame pointer or not
     fcn->addFnAttr("no-frame-pointer-elim", noFpElim_ ? "true" : "false");
 
     // no-return
-    if (no_return)
+    if ((flags & Backend::function_does_not_return) != 0)
       fcn->addFnAttr(llvm::Attribute::NoReturn);
 
     // attributes for target CPU and features
@@ -2615,16 +2610,17 @@
                                    typeManager());
 
   // split-stack or nosplit
-  if (!useSplitStack_ || disable_split_stack)
+  if (!useSplitStack_ || (flags & Backend::function_no_split_stack) != 0)
     bfunc->setSplitStack(Bfunction::NoSplit);
 
   // TODO: unique section support. llvm::GlobalObject has support for
   // setting COMDAT groups and section names, but there doesn't seem
   // to be an interface available to request a unique section on a
   // per-function basis (only a translation-unit-wide default).
-  assert(!in_unique_section || is_declaration);
+  assert((flags & Backend::function_in_unique_section) == 0 ||
+         (flags & Backend::function_is_declaration) != 0);
 
-  if (is_declaration) {
+  if ((flags & Backend::function_is_declaration) != 0) {
     fcnNameAndType candidate(std::make_pair(ft, fns));
     fcnDeclMap_[candidate] = bfunc;
   }
diff --git a/bridge/go-llvm.h b/bridge/go-llvm.h
index 7250ed2..2c68fa8 100644
--- a/bridge/go-llvm.h
+++ b/bridge/go-llvm.h
@@ -303,10 +303,8 @@
   Bfunction *error_function();
 
   Bfunction *function(Btype *fntype, const std::string &name,
-                      const std::string &asm_name, bool is_visible,
-                      bool is_declaration, bool is_inlinable,
-                      bool disable_split_stack, bool does_not_return,
-                      bool in_unique_section, Location);
+                      const std::string &asm_name, unsigned flags,
+                      Location);
 
   Bstatement *function_defer_statement(Bfunction *function,
                                        Bexpression *undefer, Bexpression *defer,
diff --git a/unittests/BackendCore/BackendCallTests.cpp b/unittests/BackendCore/BackendCallTests.cpp
index 9cd6557..82a3216 100644
--- a/unittests/BackendCore/BackendCallTests.cpp
+++ b/unittests/BackendCore/BackendCallTests.cpp
@@ -58,12 +58,9 @@
 
   // Declare a function bar with no args and no return.
   Btype *befty = mkFuncTyp(be, L_END);
-  bool is_decl = true; bool is_inl = false;
-  bool is_vis = true; bool is_split = true;
-  bool is_noret = false; bool is_uniqsec = false;
-  Bfunction *befcn = be->function(befty, "bar", "bar",
-                                  is_vis, is_decl, is_inl, is_split,
-                                  is_noret, is_uniqsec, loc);
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration);
+  Bfunction *befcn = be->function(befty, "bar", "bar", fflags, loc);
 
   // Create call to it
   Bexpression *fn = be->function_code_expression(befcn, loc);
@@ -92,12 +89,12 @@
   Btype *bi32t = be->integer_type(false, 32);
   Btype *bi8t = be->integer_type(false, 8);
   BFunctionType *befty1 = mkFuncTyp(be,
-                            L_PARM, be->pointer_type(bi8t),
-                            L_RES, be->pointer_type(bi8t),
-                            L_RES, be->pointer_type(bi32t),
-                            L_RES, be->pointer_type(bi64t),
-                            L_RES, bi64t,
-                            L_END);
+                                    L_PARM, be->pointer_type(bi8t),
+                                    L_RES, be->pointer_type(bi8t),
+                                    L_RES, be->pointer_type(bi32t),
+                                    L_RES, be->pointer_type(bi64t),
+                                    L_RES, bi64t,
+                                    L_END);
   Bfunction *func = h.mkFunction("foo", befty1);
 
   // Emit a suitable return suitable for "foo" as declared above.
@@ -175,12 +172,10 @@
   Location loc;
 
   // Declare a function 'noret' with no args and no return.
-  bool is_decl = true; bool is_inl = false;
-  bool is_vis = true; bool is_split = true;
-  bool is_noret = true; bool is_uniqsec = false;
-  Bfunction *nrfcn = be->function(befty, "noret", "noret",
-                                  is_vis, is_decl, is_inl, is_split,
-                                  is_noret, is_uniqsec, loc);
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration |
+                     Backend::function_does_not_return);
+  Bfunction *nrfcn = be->function(befty, "noret", "noret", fflags, loc);
 
   // Create a block containing two no-return calls. The intent here is to make
   // sure that the bridge detects and deletes instructions appearing downstream
diff --git a/unittests/BackendCore/BackendFcnTests.cpp b/unittests/BackendCore/BackendFcnTests.cpp
index dc76909..8c8a627 100644
--- a/unittests/BackendCore/BackendFcnTests.cpp
+++ b/unittests/BackendCore/BackendFcnTests.cpp
@@ -78,10 +78,6 @@
   BFunctionType *befty =
       mkFuncTyp(be.get(), L_PARM, bi32t, L_PARM, bi32t, L_RES, bi64t, L_END);
 
-  // FIXME: this is not supported yet.
-  bool in_unique_section = false;
-
-  const bool is_declaration = true;
   const bool is_visible[2] = {true, false};
   const bool is_inlinable[2] = {true, false};
   bool split_stack[2] = {true, false};
@@ -90,13 +86,19 @@
   unsigned count = 0;
   for (auto vis : is_visible) {
     for (auto inl : is_inlinable) {
-      for (auto split : split_stack) {
+      for (auto nosplit : split_stack) {
         for (auto noret : is_noret) {
+          unsigned fflags =
+              (Backend::function_is_declaration |
+               (vis ? Backend::function_is_visible : 0) |
+               (inl ? Backend::function_is_inlinable : 0) |
+               (nosplit ? Backend::function_no_split_stack : 0) |
+               (noret ? Backend::function_does_not_return : 0));
+
           std::stringstream ss;
           ss << "fcn" << count++;
           Bfunction *befcn =
-              be->function(befty, "_foo", ss.str(), vis, is_declaration,
-                           inl, split, noret, in_unique_section, loc);
+              be->function(befty, "_foo", ss.str(), fflags, loc);
           llvm::Function *llfunc = befcn->function();
           ASSERT_TRUE(llfunc != NULL);
           EXPECT_EQ(llfunc->getName(), ss.str());
@@ -105,7 +107,7 @@
           EXPECT_EQ(llfunc->hasFnAttribute(Attribute::NoReturn), noret);
           EXPECT_EQ(llfunc->hasExternalLinkage(), vis);
           EXPECT_EQ(llfunc->hasInternalLinkage(), !vis);
-          EXPECT_EQ(befcn->splitStack() == Bfunction::YesSplit, !split);
+          EXPECT_EQ(befcn->splitStack() == Bfunction::YesSplit, !nosplit);
         }
       }
     }
@@ -117,8 +119,10 @@
 
   // Try to create a function with an error type -- we should
   // get back error_function
-  Bfunction *mistake = be->function(be->error_type(), "bad", "bad", true, true,
-                                    false, false, false, false, loc);
+  unsigned fflags = (Backend::function_is_declaration |
+                     Backend::function_is_visible);
+  Bfunction *mistake = be->function(be->error_type(), "bad", "bad",
+                                    fflags, loc);
   EXPECT_EQ(mistake, be_error_fcn);
 }
 
@@ -241,24 +245,15 @@
   Btype *bi64t = be->integer_type(false, 64);
   BFunctionType *befty1 = mkFuncTyp(be, L_RES, bi32t, L_PARM, bi64t, L_END);
   BFunctionType *befty2 = mkFuncTyp(be, L_RES, bi64t, L_PARM, bi64t, L_END);
-  bool is_visible = true;
-  bool is_declaration = true;
-  bool is_inl = true;
-  bool is_splitstack = true;
-  bool in_unique_section = false;
-  bool is_noret = false;
-  Bfunction *bf1 =
-      be->function(befty1, "_foo", "bar", is_visible, is_declaration,
-                   is_inl, is_splitstack, is_noret, in_unique_section, loc);
-  Bfunction *bf2 =
-      be->function(befty1, "_foo", "bar", is_visible, is_declaration,
-                   is_inl, is_splitstack, is_noret, in_unique_section, loc);
-  Bfunction *bf3 =
-      be->function(befty1, "_foo", "bar", is_visible, !is_declaration,
-                   is_inl, is_splitstack, is_noret, in_unique_section, loc);
-  Bfunction *bf4 =
-      be->function(befty2, "_foo", "bar", is_visible, is_declaration,
-                   is_inl, is_splitstack, is_noret, in_unique_section, loc);
+  unsigned fflags =
+      (Backend::function_is_declaration |  Backend::function_is_visible |
+       Backend::function_is_inlinable);
+  Bfunction *bf1 = be->function(befty1, "_foo", "bar", fflags, loc);
+  Bfunction *bf2 = be->function(befty1, "_foo", "bar", fflags, loc);
+  unsigned fflags2 = (Backend::function_is_visible |
+                      Backend::function_is_inlinable);
+  Bfunction *bf3 = be->function(befty1, "_foo", "bar", fflags2, loc);
+  Bfunction *bf4 = be->function(befty2, "_foo", "bar", fflags, loc);
   EXPECT_EQ(bf1, bf2);
   EXPECT_NE(bf1, bf3);
   EXPECT_NE(bf2, bf4);
@@ -394,18 +389,11 @@
                                   L_END);
 
   // Now manufacture Bfunctions
-  bool visible = true;
-  bool is_declaration = true;
-  bool is_inl = true;
-  bool split_stack = false;
-  bool unique_sec = false;
-  bool no_ret = false;
-  Bfunction *bf1 = be->function(btf1, "syscall", "syscall", visible,
-                                is_declaration, is_inl,
-                                split_stack, no_ret, unique_sec, loc);
-  Bfunction *bf2 = be->function(btf2, "syscall", "syscall", visible,
-                                is_declaration, is_inl,
-                                split_stack, no_ret, unique_sec, loc);
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration |
+                     Backend::function_is_inlinable);
+  Bfunction *bf1 = be->function(btf1, "syscall", "syscall", fflags, loc);
+  Bfunction *bf2 = be->function(btf2, "syscall", "syscall", fflags, loc);
 
   // Create calls to the functions
 
@@ -463,27 +451,19 @@
                                   L_END);
 
   // Now manufacture Bfunctions
-  bool visible = true;
-  bool is_inl = true;
-  bool split_stack = false;
-  bool unique_sec = false;
-  bool no_ret = false;
+  unsigned fflags1 = (Backend::function_is_visible |
+                      Backend::function_is_inlinable);
+  unsigned fflags2 = (Backend::function_is_visible |
+                      Backend::function_is_declaration |
+                      Backend::function_is_inlinable);
 
   // bar() declaration and definition
-  Bfunction *bf1 = be->function(btf1, "bar", "bar", visible,
-                                true, // is_declaration
-                                is_inl, split_stack, no_ret, unique_sec, loc);
-  Bfunction *bf2 = be->function(btf1, "bar", "bar", visible,
-                                false, // is_declaration
-                                is_inl, split_stack, no_ret, unique_sec, loc);
+  Bfunction *bf1 = be->function(btf1, "bar", "bar", fflags2, loc);
+  Bfunction *bf2 = be->function(btf1, "bar", "bar", fflags1, loc);
 
   // baz() declaration and definition
-  Bfunction *bf3 = be->function(btf2, "baz", "baz", visible,
-                                true, // is_declaration
-                                is_inl, split_stack, no_ret, unique_sec, loc);
-  Bfunction *bf4 = be->function(btf3, "baz", "baz", visible,
-                                false, // is_declaration
-                                is_inl, split_stack, no_ret, unique_sec, loc);
+  Bfunction *bf3 = be->function(btf2, "baz", "baz", fflags2, loc);
+  Bfunction *bf4 = be->function(btf3, "baz", "baz", fflags1, loc);
 
   // Create calls to the functions
   Bexpression *call1 = h.mkCallExpr(be, bf1, nullptr);
diff --git a/unittests/BackendCore/BackendStmtTests.cpp b/unittests/BackendCore/BackendStmtTests.cpp
index 197e6e1..3064bf4 100644
--- a/unittests/BackendCore/BackendStmtTests.cpp
+++ b/unittests/BackendCore/BackendStmtTests.cpp
@@ -512,15 +512,13 @@
 
   // Declare checkdefer, deferreturn
   Btype *befty = mkFuncTyp(be, L_PARM, be->pointer_type(bi8t), L_END);
-  bool is_decl = true; bool is_inl = false;
-  bool is_vis = true; bool is_split = true;
-  bool is_noret = false; bool is_uniqsec = false;
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration);
   Bfunction *bchkfcn = be->function(befty, "checkdefer", "checkdefer",
-                                    is_vis, is_decl, is_inl, is_split,
-                                    is_noret, is_uniqsec, h.newloc());
+                                    fflags, h.newloc());
   Bfunction *bdefretfcn = be->function(befty, "deferreturn", "deferreturn",
-                                       is_vis, is_decl, is_inl, is_split,
-                                       is_noret, is_uniqsec, h.newloc());
+                                       fflags, h.newloc());
+
 
   // Materialize call to deferreturn
   Bexpression *retfn = be->function_code_expression(bdefretfcn, h.newloc());
@@ -608,32 +606,28 @@
                                     L_RES, bi64t,
                                     L_END);
 
-  bool is_decl = true; bool is_inl = false;
-  bool is_vis = true; bool is_split = true;
-  bool is_noret = false; bool is_uniqsec = false;
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration);
   const char *fnames[] = { "plark", "plix" };
   Bfunction *fcns[4];
   Bexpression *calls[5];
   for (unsigned ii = 0; ii < 2; ++ii)  {
-    fcns[ii] = be->function(befty, fnames[ii], fnames[ii],
-                            is_vis, is_decl, is_inl, is_split,
-                            is_noret, is_uniqsec, h.newloc());
+    fcns[ii] = be->function(befty, fnames[ii], fnames[ii], fflags, h.newloc());
     Bexpression *pfn = be->function_code_expression(fcns[ii], h.newloc());
     std::vector<Bexpression *> args;
     calls[ii] = be->call_expression(func, pfn, args,
                                     nullptr, h.newloc());
   }
-  fcns[2] = be->function(befty2, "id", "id",
-                         is_vis, is_decl, is_inl, is_split,
-                         is_noret, is_uniqsec, h.newloc());
+  fcns[2] = be->function(befty2, "id", "id", fflags, h.newloc());
   Bexpression *idfn = be->function_code_expression(fcns[2], h.newloc());
   std::vector<Bexpression *> iargs;
   iargs.push_back(mkInt64Const(be, 99));
   calls[2] = be->call_expression(func, idfn, iargs,
                                  nullptr, h.newloc());
-  fcns[3] = be->function(beftynr, "noret", "noret",
-                         is_vis, is_decl, is_inl, is_split,
-                         true, is_uniqsec, h.newloc());
+  unsigned fflags2 = (Backend::function_is_visible |
+                      Backend::function_does_not_return |
+                      Backend::function_is_declaration);
+  fcns[3] = be->function(beftynr, "noret", "noret", fflags2, h.newloc());
   for (unsigned ii = 0; ii < 2; ++ii)  {
     Bexpression *nrfn = be->function_code_expression(fcns[3], h.newloc());
     std::vector<Bexpression *> noargs;
@@ -807,12 +801,9 @@
   Bfunction *func = h.mkFunction("baz", befty);
   Bvariable *rtmp = h.mkLocal("ret", bi64t);
 
-  bool is_decl = true; bool is_inl = false;
-  bool is_vis = true; bool is_split = true;
-  bool is_noret = false; bool is_uniqsec = false;
-  Bfunction *sfn = be->function(befty, "splat", "splat",
-                                is_vis, is_decl, is_inl, is_split,
-                                is_noret, is_uniqsec, h.newloc());
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_declaration);
+  Bfunction *sfn = be->function(befty, "splat", "splat", fflags, h.newloc());
   Bexpression *splfn = be->function_code_expression(sfn, h.newloc());
   Btype *bi8t = be->integer_type(false, 8);
   Bvariable *loc1 = h.mkLocal("x", bi8t);
diff --git a/unittests/BackendCore/BackendTreeIntegrity.cpp b/unittests/BackendCore/BackendTreeIntegrity.cpp
index ab9fb8e..c82ef1f 100644
--- a/unittests/BackendCore/BackendTreeIntegrity.cpp
+++ b/unittests/BackendCore/BackendTreeIntegrity.cpp
@@ -171,11 +171,11 @@
   BFunctionType *bfterr = mkFuncTyp(be,
                                     L_PARM, bi32t,
                                     L_END);
-  bool visible = true;  bool is_inl = true;
-  bool split_stack = false;  bool uniq_sec = false;
-  bool no_ret = true; bool is_decl = true;
-  Bfunction *rtefcn = be->function(bfterr, rtename, rtename, visible, is_decl,
-                                   is_inl, split_stack, no_ret, uniq_sec, loc);
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_inlinable |
+                     Backend::function_does_not_return |
+                     Backend::function_is_declaration);
+  Bfunction *rtefcn = be->function(bfterr, rtename, rtename, fflags, loc);
 
   // p0 != nil ? *p0 + 3 : runtime_error(6)
   Bexpression *cmp2 =
diff --git a/unittests/BackendCore/TestUtils.cpp b/unittests/BackendCore/TestUtils.cpp
index 2699203..9bff12a 100644
--- a/unittests/BackendCore/TestUtils.cpp
+++ b/unittests/BackendCore/TestUtils.cpp
@@ -213,16 +213,10 @@
       mkFuncTyp(be,
                 L_PARM, bi32t, L_PARM, bi32t, L_PARM, bpi64t,
                 L_RES, bi64t, L_END);
-  bool visible = true;
-  bool is_declaration = false;
-  bool is_inl = true;
-  bool split_stack = true;
-  bool unique_sec = false;
-  bool no_ret = false;
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_inlinable);
   Location loc;
-  Bfunction *func = be->function(befty, fname, fname, visible,
-                                 is_declaration, is_inl,
-                                 split_stack, no_ret, unique_sec, loc);
+  Bfunction *func = be->function(befty, fname, fname, fflags, loc);
   if (mkParams) {
     be->parameter_variable(func, "param1", bi32t, false, loc);
     be->parameter_variable(func, "param2", bi32t, false, loc);
@@ -234,15 +228,9 @@
 Bfunction *mkFuncFromType(Backend *be, const char *fname,
                           BFunctionType *befty, Location loc)
 {
-  bool visible = true;
-  bool is_declaration = false;
-  bool is_inl = true;
-  bool split_stack = true;
-  bool unique_sec = false;
-  bool no_ret = false;
-  Bfunction *func = be->function(befty, fname, fname, visible,
-                                 is_declaration, is_inl,
-                                 split_stack, no_ret, unique_sec, loc);
+  unsigned fflags = (Backend::function_is_visible |
+                     Backend::function_is_inlinable);
+  Bfunction *func = be->function(befty, fname, fname, fflags, loc);
   const std::vector<Btype *> &paramTypes = befty->paramTypes();
   for (unsigned idx = 0; idx < paramTypes.size(); ++idx) {
     std::stringstream ss;