gollvm: refactor temp variable generation
There are a few places where we need to create a temporary
varaible holding the value of an expression. Make a helper
function for this.
Change-Id: I75c11e462d770020069953454b6ad9fd7029d62d
Reviewed-on: https://go-review.googlesource.com/45750
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/llvm-gofrontend/go-llvm.cpp b/llvm-gofrontend/go-llvm.cpp
index d1c22fa..c29fd0a 100644
--- a/llvm-gofrontend/go-llvm.cpp
+++ b/llvm-gofrontend/go-llvm.cpp
@@ -911,6 +911,22 @@
return VE_rvalue;
}
+// Create a temporary variable holding the value of EXPR.
+// Return the variable and the assignment statement (to be
+// attached to some node).
+
+std::pair<Bvariable*, Bstatement*>
+Llvm_backend::makeTempVar(Bexpression *expr, Location location) {
+ assert(expr);
+ std::string tname(namegen("tmp"));
+ Bvariable *var = nbuilder_.mkTempVar(expr->btype(), location, tname);
+ assert(var != errorVariable_.get());
+ Bfunction *dummyFcn = errorFunction_.get();
+ Bstatement *init = makeInitStatement(dummyFcn, var, expr);
+ assert(init != errorStatement_);
+ return std::make_pair(var, init);
+}
+
// An expression that references a variable.
Bexpression *Llvm_backend::var_expression(Bvariable *var,
@@ -1400,10 +1416,9 @@
// We need to avoid sharing between real part and imag part of the operand.
// Create temp variables and assign operand to the temp variable first.
// TODO: maybe not make temp var if the operand is already a var or constant?
- std::string tname1(namegen("tmp"));
- Bvariable *var = nbuilder_.mkTempVar(expr->btype(), location, tname1);
- Bfunction *dummyFcn = errorFunction_.get();
- Bstatement *einit = makeInitStatement(dummyFcn, var, expr);
+ auto p = makeTempVar(expr, location);
+ Bvariable *var = p.first;
+ Bstatement *einit = p.second;
Bexpression *vex = nbuilder_.mkVar(var, location);
vex->setVarExprPending(false, 0);
@@ -1419,9 +1434,9 @@
// Currently we can't resolve composite storage for compound
// expression, so we resolve the inner complex expression
// here with another temp variable.
- std::string tname2(namegen("tmp"));
- Bvariable *rvar = nbuilder_.mkTempVar(val->btype(), location, tname2);
- Bstatement *rinit = makeInitStatement(dummyFcn, rvar, val);
+ auto p2 = makeTempVar(val, location);
+ Bvariable *rvar = p2.first;
+ Bstatement *rinit = p2.second;
Bexpression *rvex = nbuilder_.mkVar(rvar, location);
Bstatement *init = statement_list(std::vector<Bstatement*>{einit, rinit});
return compound_expression(init, rvex, location);
@@ -1910,12 +1925,9 @@
// We need to avoid sharing between real part and imag part of the operand.
// Create temp variables and assign operands to the temp vars first.
// TODO: maybe not make temp var if the operand is already a var or constant?
- std::string tname1(namegen("tmp")), tname2(namegen("tmp"));
- Bvariable *lvar = nbuilder_.mkTempVar(left->btype(), location, tname1);
- Bvariable *rvar = nbuilder_.mkTempVar(right->btype(), location, tname2);
- Bfunction *dummyFcn = errorFunction_.get();
- Bstatement *linit = makeInitStatement(dummyFcn, lvar, left);
- Bstatement *rinit = makeInitStatement(dummyFcn, rvar, right);
+ auto p = makeTempVar(left, location), p2 = makeTempVar(right, location);
+ Bvariable *lvar = p.first, *rvar = p2.first;
+ Bstatement *linit = p.second, *rinit = p2.second;
Bexpression *lvex = nbuilder_.mkVar(lvar, location);
lvex->setVarExprPending(false, 0);
@@ -1966,9 +1978,9 @@
// Currently we can't resolve composite storage for compound
// expression, so we resolve the inner complex expression
// here with another temp variable.
- std::string tname3(namegen("tmp"));
- Bvariable *vvar = nbuilder_.mkTempVar(val->btype(), location, tname3);
- Bstatement *vinit = makeInitStatement(dummyFcn, vvar, val);
+ auto p3 = makeTempVar(val, location);
+ Bvariable *vvar = p3.first;
+ Bstatement *vinit = p3.second;
Bexpression *vvex = nbuilder_.mkVar(vvar, location);
Bstatement *init = statement_list(std::vector<Bstatement*>{linit, rinit, vinit});
return compound_expression(init, vvex, location);
diff --git a/llvm-gofrontend/go-llvm.h b/llvm-gofrontend/go-llvm.h
index 59747da..81f7874 100644
--- a/llvm-gofrontend/go-llvm.h
+++ b/llvm-gofrontend/go-llvm.h
@@ -481,6 +481,11 @@
Bstatement *makeInitStatement(Bfunction *bfunction, Bvariable *var,
Bexpression *init);
+ // Helper to make a temporary variable holding the value of an
+ // expression
+ std::pair<Bvariable*, Bstatement*> makeTempVar(Bexpression *expr,
+ Location location);
+
// Helper to set up entry block for function
llvm::BasicBlock *genEntryBlock(Bfunction *bfunction);
diff --git a/unittests/BackendCore/BackendExprTests.cpp b/unittests/BackendCore/BackendExprTests.cpp
index 0b045d9..2c89898 100644
--- a/unittests/BackendCore/BackendExprTests.cpp
+++ b/unittests/BackendCore/BackendExprTests.cpp
@@ -1003,8 +1003,8 @@
%tmp.3 = alloca { double, double }
%tmp.2 = alloca { double, double }
%tmp.5 = alloca { double, double }
- %tmp.1 = alloca { double, double }
%tmp.0 = alloca { double, double }
+ %tmp.1 = alloca { double, double }
%x = alloca { double, double }
%y = alloca { double, double }
%z = alloca { double, double }