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 }