/* ---------------------------------------------------------------------
%   Copyright (C) 2007 Association for the COINS Compiler Infrastructure
%       (Read COPYING for detailed information.)
--------------------------------------------------------------------- */
package coins.ir;

import coins.sym.FlowAnalSym;
import coins.sym.Sym;

//========================================//
//                           //##54: Moved to IR0 on Nov. 2004
//                           //##20: modified on Feb. 2003.

/** IR
<PRE>
 * Intermediate Representation (IR) interface
 *
 *  Intermediate representation of programs consists of
 *  following kinds of information:
 *
 *    High level intermediate representation (HIR)
 *      Abstract representation of the logical structure of
 *      source programs.
 *
 *    Low level intermediate representation (LIR)
 *      Abstract representation of computer operations corresponding
 *      to the source program.
 *
 *    Symbol table
 *      Inforamtion of symbols used in the source program and
 *      symbols generated by the compiler such as registers, temporals,
 *      internal labels.
 *
 *    Flow information
 *      Control flow, data flow information, loop information,
 *      and parallelization information.
 *
 *  These components are linked with each other so that various
 *  information can be get quickly for optimization and
 *  parallelization of the program.
 *
 *  The IR interface declares methods that are common between HIR
 *  and LIR. By using them, we can make modules that are applicable
 *  both to HIR and LIR which implement IR interface.
 *    HIR class implements HIR interface and IR interface.
 *    LIR class implements LIR interface and IR interface.
 *
 *  In HIR, operation is represented by a tree where each of its
 *  subtree represents some logical construct of source program
 *  mostly language-independent and machine-independent mannar.
 *
 *  In LIR, operation is represented by a tree each node of which
 *  either represents abstract machine instruction or control
 *  information. The abstract machine instructions may represent
 *  information specific to a target machine but they take common
 *  format so that LIR processing routines can be made common to
 *  various target machines.
 *
 *  Each subtree has a root node to which other nodes are connected
 *  directly or indirectly. A node having one or more children is
 *  called nonleaf. A node having no child is called leaf.
 *  Each subtree is represented by its root node.
 *  A child of the root node (node connected directly to the root
 *  node) in a subtree is a source operand of the root node and the
 *  root node itself represents the result of the expression
 *  represented by the subtree.
 *  A subtree can be changed to a sequence of nodes by traversing it
 *  in depth-first order from left to right.
 *
 *  An LIR subtree representing a machine operation is sometimes
 *  called an instruction.  Operands of the LIR instruction may be
 *  an abstract register or a symbol (such as variable or constant
 *  or label) or other instruction subtree.
 *
 *  Each node of HIR or LIR has index number to identify it if it
 *  represents an executable operation. The index number may be
 *  used in procedures analyzing or transforming the program
 *  represented either in HIR or LIR for optimization and
 *  parallelization.
 *  The analysis/transformation procedures can be coded to be
 *  applicable both to HIR and LIR by using methods described
 *  in this interface.
 *
 *  Each node of HIR is attached with HIR type that represents the
 *  type of expression represented by the node. The HIR type may be
 *  base type defined in this compiler system, or a type
 *  defined in the input program or class introduced by input
 *  language or defined by the input program. If the node is such
 *  one as having no value (neither r-value nore l-value), then null
 *  is attached as its data type.
 *  Each node of LIR is attached with basic type such as
 *  I8, I32, F32, F64, etc. representing the type of the value or
 *  address represented by the node. Aggregate data type or class
 *  are decomposed into basic types when HIR is transformed into LIR
 *  by decomposing aggregates into its elements.
 *
 *  Creation of HIR tree can be done by using HIR factory methods
 *  (as shown in HIR.java).
 *  Creation of LIR instruction sequence can be done by using
 *  LIR factory methods.
</PRE>
**/
public interface
IR extends IR0, Cloneable
{

//======= Methods for attached information ======//
//        See reserved information identifiers in coins.Registry.java.

/** addInf
 *  Add (attach) information pInfObject to this IR node.
 *  If information of the same kind is already exists in this node,
 *  then the old one is replaced with the new one (pInfObject).
 *  @param pInfKindInterned The kind name of the information to be added.
 *      It should be interned (in such way as "coins_pragma".intern()).
 *      The kind names are listed in coins.Registry class.
 *  @param pInfObject Object to be added as information.
 *      It may be String, Sym, IR, List, and so on,
 *      hence they may be non-IR elements.
**/
public void
addInf( String pInfnKindInterned, Object pInfObject );
// Among Inf treatment methods, getInf is used in hir2c.
// There is no other usage at 040108

/** getInf
 *  Get the information of the kind pInfKindInterned.
 *  If there is no information of the specified kind,
 *  then null is returned.
 *  The kind names are listed in coins.Registry class.
 *  It should be interned (in such way as "coins_pragma".intern()).
 *  If there is no information of the kind pInfKindInterned,
 *  then return null.
 *  Note that the value returned by getInf is not restricted to
 *  IR objects but it may be Sym, Const, String.
 *  @param pInfKindInterned The kind name of the information to be get.
 *  @return the object of the specified kind attached to this node.
**/
public Object
getInf( String pInfIdInterned);

/** removeInf
 *  Remove the information of the kind pInfKindInterned.
 *  If there is no information of the specified kind,
 *  then no effect remains.
 *  @param pInfKindInterned The kind name of the information to be removed.
 *      The kind names are listed in Registry class.
 *      It should be interned (in such way as "coins_pragma".intern()).
**/
public void
removeInf( String pInfIdInterned); //##17

/** getInfList
 *  Get the information list attached to this node.
 *  If no information is added, then null is returned.
 *  You can see if information is added or not by
 *    if (node.getInfList() == null) ....
 *  This method is prepared for persons who knows well
 *  the inside of the compiler.
 *  In ordinary usage, this method is unnecessary to be used.
 *  If you want to see the contents of the list, you should know
 *  the structure of the list defined in HirAnnex and LirAnnex.
**/
public IrList
getInfList();

//==== Methods to set/get informatin to/from IR node ====//

/** getIndex
 *  Get the index number assigned to "this" node.
 *  (The index number is used to refer the node in data flow analysis
 *   and debug-print.)
 *  @return the index number assigned to "this" node.
 *      If the node has no index number, return 0.
**/
//##54 int
//##54 getIndex();

/** getSym
 *  Get the symbol represented by "this" node if
 *  this is a node representing a symbol (simple variable,
 *  element/field name, subprogram, label, constant, etc.).
 *  @return the symbol represented by "this" node.
 *      In HIR, it is
 *        Var   if VarNode
 *        Subp  if SubpNode,
 *        Label if LabelNode or LabelDef
 *        Elem  if ElemNode
 *     // Field if FieldNode
 *        Const if ConstNode.
 *      If "this" node does not represent any symbol, then return
 *      null. (If "this" is HIR leaf or nonleaf node, the symbol
 *      attached to the node is returned. If "this" has no symbol
 *      attached, then return null.
 *      If "this" is LIR node representing a symbol, the symbol is
 *      returned. If "this" is LIR computation node, null is
 *      returned.)
**/
Sym
getSym();

//======================================================//
//  Following methods require special attention to keep
//  consistency between internal representations.
//======================================================//

/** getParent
 *  Get the parent of this node.
 *  @return the parent of this node.
 *      If this has no parent, return null.
**/
public IR
getParent();

/** getOperator
 *  Get operation code of "this" node.
 *  @return the operation code (value of operator field) of
 *      "this" node.
**/
//##54 int
//##54 getOperator();

//====== Methods for printing ======//

/** print
 *  Print this subtree in text format traversing all children
 *  of this node.
 *  "this" may be any subtree (it may be a leaf node).
 *  @param pIndent number of heading spaces for indentation.
 *  @param pDetail true if detail print is requested, false otherwise.
**/
public void print( int pIndent );

/** print
 *  Print this subtree in text format traversing all children
 *  of this node.
 *  "this" may be any subtree (it may be a leaf node).
 *  @param pIndent number of heading spaces for indentation.
 *  @param pDetail true if detail print is requested, false otherwise.
**/
public void print( int pIndent, boolean pDetail );

//===================//
//    Constants      //
//===================//

/** Operation codes for IR node .
 *  They are the same to those defined in HIR interface.
**/
  public static final int    // Operator number:
                             // (See HIR, too.)
    OP_PROG          =  1,   // Program
    OP_SUBP_DEF      =  2,   // SubpDefinition
//##54     OP_LABEL_DEF     =  3,   // LabelDef node
    OP_INF           =  4,
//##54     OP_CONST         =  5,   // ConstNode
//##54     OP_SYM           =  6,   // SymNode
//##54     OP_VAR           =  7,   // VarNode
//##54     OP_PARAM         =  8,   // VarNode
//##54     OP_SUBP          =  9,   // SubpNode
//##54     OP_TYPE          = 10,   // TypeNode
//##54     OP_LABEL         = 11,   // LabelNode
//##54     OP_ELEM          = 12,   // ElemNode
//##54  // OP_FIELD         = 13,
    OP_LIST       = 14;   // List
//##54     OP_SEQ        = 15;   // Sequence

/** OP_CODE_NAME Operation code name corresonding to
 *  the above operation code.
**/
  public static final String[]      // Operation code name.
    OP_CODE_NAME = {          "none00  ",
      "prog    ", "subpDef ", "labelDef", "inf     ", "const   ",
      "sym     ", "var     ", "param   ", "subp    ", "type    ",
      "label   ", "elem    ", "none13  ", "list    ", "seq     "
    };

//====== Reserved name of information kind attached to IR nodes ======//
//       Names beginning with "coins_" are reserved for basic part
//       of this compiler.
//       Followings are moved to coins.Registry.java.
// public static final String
//   INF_KIND_IR      = "coins_inf".intern(),     // for IR node,
//   INF_KIND_COMMENT = "coins_comment".intern(), // for comment,
//   INF_KIND_OPEN_MP = "coins_omp".intern(),     // for OpenMP;
//   INF_KIND_HIR2C   = "coins_hir2c".intern();   // for HIR to C

//====== Methods that are not inevitable (may be deleted) ======//

//---- Methods to link child to IR node ----//

/** getChildCount
 *  Get the number of children that may be attached to this node.
 *  Abbreviated child (null child) is also counted.
 *  @return the number of children of this node.
**/
//##54 public int
//##54 getChildCount();

/** getChild1
 *  Get the first child of this node.
 *  (This method does the same operation as getChild(1) but
 *  it may be more efficient.)
 *  @return the child 1 of this node.
**/
public IR
getChild1();

/** getChild2
 *  Get the second child of this node.
 *  (This method does the same operation as getChild(2) but
 *  it may be more efficient.)
 *  @return the child 2 of this node.
**/
public IR
getChild2();

/** getChild
 *  @param pNumber the child number of the child to be returned.
 *  @return the specified child of this node.
**/
//##54 public IR
//##54 getChild( int pNumber );

/** setChild
 *  Set pHir as pNumber-th child of this node.
 *  @param pNumber Child number
 *  @param pIR Child node to be connected.
**/
//##54 public void
//##54 setChild( int pNumber, IR pIr );

public String //##60
  toStringShort(); //##60

} // IR interface

