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 *> ¶mTypes = befty->paramTypes();
for (unsigned idx = 0; idx < paramTypes.size(); ++idx) {
std::stringstream ss;