//===-- go-llvm-bexpression.h - decls for gofrontend 'Bexpression' class --===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Defines Bexpression and related classes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVMGOFRONTEND_GO_LLVM_BEXPRESSION_H
#define LLVMGOFRONTEND_GO_LLVM_BEXPRESSION_H

// Currently these need to be included before backend.h
#include "go-llvm-linemap.h"
#include "go-location.h"
#include "go-llvm-btype.h"
#include "go-llvm-bnode.h"

#include "backend.h"

namespace llvm {
class Instruction;
class Value;
class raw_ostream;
}

class Bstatement;
class BnodeBuilder;

// Mixin class for a list of instructions

class Binstructions {
public:
  Binstructions() {}
  explicit Binstructions(const std::vector<llvm::Instruction *> &instructions)
      : instructions_(instructions) {}

  const std::vector<llvm::Instruction *> &instructions() const {
    return instructions_;
  }
  void appendInstruction(llvm::Instruction *inst) {
    assert(isValidInst(inst));
    instructions_.push_back(inst);
  }
  void appendInstructions(const std::vector<llvm::Instruction *> &ilist) {
    for (auto inst : ilist) {
      assert(isValidInst(inst));
      instructions_.push_back(inst);
    }
  }

  void clear() { instructions_.clear(); }

private:
  std::vector<llvm::Instruction *> instructions_;

  // Certain classes of instructions should not be hanging off a
  // Bexpression -- they should only appear in a function prolog.
  bool isValidInst(llvm::Instruction *);
};

// Helper class used as part of class Bexpression. This object records
// whether a Bexpression subtree contains a root variable expression,
// and if so, whether that variable expression appears in an "lvalue"
// (left-hand-side of assignment) or "rvalue" (right hand side of
// assignment) context, as whether a address operator has been applied
// to the variable.  Once we reach a point where we have concrete
// consumer for the subtree of (var/address/indrect/field/indexing)
// ops, we can then use this information to decide whether to
// materialize an address or perform a load. See the main Bexpression
// comment for more info here.

class VarContext {
 public:
  VarContext() : addrLevel_(0), lvalue_(false), pending_(false) { }
  VarContext(bool lvalue, unsigned addrLevel)
      : addrLevel_(addrLevel), lvalue_(lvalue), pending_(true) { }
  explicit VarContext(const VarContext &src)
      : addrLevel_(src.addrLevel_), lvalue_(src.lvalue_),
        pending_(src.pending_)
  { }

  bool pending() const { return pending_; }
  unsigned addrLevel() const { return addrLevel_; }
  bool lvalue() const { return lvalue_; }
  void setPending(bool lvalue, unsigned addrLevel) {
    assert(!pending_);
    pending_ = true;
    lvalue_ = lvalue;
    addrLevel_ = addrLevel;
  }
  void reset() { assert(pending_); pending_ = false; }
  bool equal(const VarContext &other) const {
    return (pending_ == other.pending_ &&
            addrLevel_ == other.addrLevel_ &&
            lvalue_ == other.lvalue_);
  }

 private:
  unsigned addrLevel_;
  bool lvalue_;
  bool pending_;
};

// Whether a variable expression appears in lvalue (assignment) context.
enum Varexpr_context {
  VE_rvalue,
  VE_lvalue
};

// Bexpression is the backend representation of an expression, meaning
// that it produces a value (llvm::Value) and will encapsulate some
// set of instructions (llvm::Instruction) needed to produce that
// value.  The overall strategy for Bexpressions is to produce LLVM
// values in an "eager" fashion, that is, any LLVM instructions needed
// to compute the expression's value are computed as soon as possible
// (typically right at the point where the Bexpression is
// constructed).  For example, if Llvm_backend::binary_operator is
// invoked to create a Bexpression for an addition operation, it will
// eagerly manufacture a new llvm::BinaryOperator object and return a
// new Bexpression that encapsulates that object.
//
// This eager strategy works well for the most part, but has to be
// relaxed in some instances, notably variable references and
// composite initializers. Consider the following Go code:
//
//    func foo(qq int64) int64 {
//      var ad [4]int64 = [4]int64{ 0, 1, qq, 3 }
//
// Frontend will invoke the Backend::array_constructor_expression()
// method for the initializer ("{ 0, 1, qq, 3 }"). Because this
// initializer is not a pure constant (it contains a reference to the
// variable "qq"), the LLVM instructions we generate for it will have
// to store the array values to a chunk of memory. At the point where
// array_constructor_expression() is called, we don't yet know what
// expression or statement the value will feed into, meaning that it
// would be premature to emit LLVM instructions to initialize that
// storage.
//
// To address this, non-constant composite expressions use a lazy
// value generation strategy; the Bexpression itself is marked as
// delayed (no LLVM value), and then once we reach the point where we
// know what the storage will be, someone makes a call to
// BnodeBuilder::finishComposite to generate the necessary store
// instructions and finalize the LLVM value.
//
// Second area where we want to delay things is in handling of
// variable expressions. For example, consider the following Go code:
//
//        struct X { a, b int64 }
//        func foo(q, r int64, ip *int64, px *X) int64 {
//           r = q
//           r = **&ip
//           ip = &q
//         px.a = px.b
//
// The right hand side expression trees for these statements would look like:
//
//        stmt 1:   varexpr("q")
//        stmt 2:   deref(deref(address(varexpr("ip")))).
//        stmt 3:   address(varexpr("q"))
//        stmt 4:   field(deref(varexpr("px"),'b')
//
// At the point where Llvm_backend::var_expression is called, we don't
// know the context for the consuming instruction. For statement 1, we
// want to generate a load for the varexpr, however in statement 3 it
// would be premature to create the load (since the varexpr is feeding
// into an address operator). This is handled using the VarContext
// helper object (define above).

class Bexpression : public Bnode, public Binstructions {
 public:
  // no public constructor, use BnodeBuilder instead
  virtual ~Bexpression();

  llvm::Value *value() const { return value_; }
  Btype *btype() const { return btype_; }
  const std::string &tag() const { return tag_; }
  void setTag(const std::string &tag) { tag_ = tag; }

  bool varExprPending() const;
  const VarContext &varContext() const;
  void setVarExprPending(bool lvalue, unsigned addrLevel);
  void setVarExprPending(const VarContext &vc);
  void resetVarExprContext();
  bool compositeInitPending() const;
  const std::vector<Bexpression *> getChildExprs() const;

  // Return context disposition based on expression type.
  // Composite values need to be referred to by address,
  // whereas non-composite values can be used directly.
  Varexpr_context varContextDisp() const;

  // Return whether the expression is a constant.
  // True implies the underlying llvm::Value is llvm::Constant.
  bool isConstant();

  // debugging
  void dumpInstructions(llvm::raw_ostream &os, unsigned ilevel,
                        Llvm_linemap *linemap, bool terse) const;

  // dump with source line info
  void srcDump(Llvm_linemap *);

  friend class BnodeBuilder;

 private:
  Bexpression(NodeFlavor fl, const std::vector<Bnode *> &kids,
              llvm::Value *val, Btype *typ, Location loc);
  Bexpression(const Bexpression &src);
  void setValue(llvm::Value *val);

  llvm::Value *value_;
  Btype *btype_;
  std::string tag_;
  VarContext varContext_;
};

#endif // LLVMGOFRONTEND_GO_LLVM_BEXPRESSION_H
