Program Listing for File IRInterface.h

Program Listing for File IRInterface.h#

Return to documentation for file (src/midend/programAnalysis/OpenAnalysis/Interface/IRInterface.h)

// $Id: IRInterface.h,v 1.2 2006/04/24 00:21:34 dquinlan Exp $
// -*-C++-*-
// * BeginRiceCopyright *****************************************************
//
// Copyright ((c)) 2002, Rice University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
//
// * Neither the name of Rice University (RICE) nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// This software is provided by RICE and contributors "as is" and any
// express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular
// purpose are disclaimed. In no event shall RICE or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or
// consequential damages (including, but not limited to, procurement of
// substitute goods or services; loss of use, data, or profits; or
// business interruption) however caused and on any theory of liability,
// whether in contract, strict liability, or tort (including negligence
// or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage.
//
// ******************************************************* EndRiceCopyright *

#ifndef IRInterface_h
#define IRInterface_h

//-----------------------------------------------------------------------------
// This file contains the abstract base classes for the IR interface.
//
// See the top level README for a description of the IRInterface and
// how to use it.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Below are generic types for handles to relate objects to a user's IR. 0 is
// reserved as a NULL value.  There are two sets of types:
//  1) one whose type/size is relative to the current platform, and
//  2) one whose type/size is maximum, which is useful for cross-platform tools
//
//   OA_IRHANDLETYPE_UL:  For handles on this platform
//   OA_IRHANDLETYPE_SZ64: Maximum size for cross-platform handles
//-----------------------------------------------------------------------------

#include "inttypes.h"

#if defined(OA_IRHANDLETYPE_UL)

  typedef unsigned long openanal_base_type;

#elif defined(OA_IRHANDLETYPE_SZ64)

  typedef uint64_t openanal_base_type;

#else

# error OpenAnalysis handle type must be specified!

#endif

typedef openanal_base_type ProcHandle;
typedef openanal_base_type StmtHandle;
typedef openanal_base_type ExprHandle;
typedef openanal_base_type LeafHandle; // An expr that happens to be a leaf.
typedef openanal_base_type StmtLabel;
typedef openanal_base_type SymHandle;


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------

// Enumerate all the procedures in a certain IR
class IRProcIterator {
public:
  IRProcIterator() { }
  virtual ~IRProcIterator() { }

  virtual ProcHandle Current() = 0;   // Returns the current item.
  virtual bool IsValid () = 0;        // False when all items are exhausted.
  virtual void operator++() = 0;
  void operator++(int) { ++*this; }

  virtual void Reset() = 0;
};

// Enumerate all the statements in a program region, e.g. all the statements
// in a procedure or a loop.
class IRStmtIterator {
public:
  IRStmtIterator() { }
  virtual ~IRStmtIterator() { };

  virtual StmtHandle Current() = 0;  // Returns the current item.
  virtual bool IsValid() = 0;        // False when all items are exhausted.
  virtual void operator++() = 0;
  void operator++(int) { operator++(); } ;

  virtual void Reset() = 0;
};

// Enumerate all the variable uses or variable definitions in a statement.
// This is useful for analyses that require information about variable
// references or definitions, such as SSA construction.
class IRUseDefIterator {
public:
  enum { Uses, Defs };

  IRUseDefIterator() { }
  virtual ~IRUseDefIterator() { }

  virtual LeafHandle Current() = 0;   // Returns the current item.
  virtual bool IsValid () = 0;        // False when all items are exhausted.
  virtual void operator++() = 0;
  void operator++(int) { ++*this; }

  virtual void Reset() = 0;
};

// Enumerate all the procedure calls in a statement.
class IRCallsiteIterator {
public:
  IRCallsiteIterator() { }
  virtual ~IRCallsiteIterator() { }

  virtual ExprHandle Current() = 0;   // Returns the current item.
  virtual bool IsValid () = 0;        // False when all items are exhausted.
  virtual void operator++() = 0;
  void operator++(int) { ++*this; }

  virtual void Reset() = 0;
};

// Enumerate all (actual) parameters within a callsite
class IRCallsiteParamIterator {
public:
  IRCallsiteParamIterator() { }
  virtual ~IRCallsiteParamIterator() { }

  virtual ExprHandle Current() = 0;   // Returns the current item.
  virtual bool IsValid () = 0;        // False when all items are exhausted.
  virtual void operator++() = 0;
  void operator++(int) { ++*this; }

  virtual void Reset() = 0;
};



// Procedures are classified into one of the following types:
enum IRProcType
{
  ProcType_PGM,
  ProcType_SUB,
  ProcType_FUNC,
  ProcType_BDATA,
  ProcType_ILLEGAL
};

// Statements are classified into one of the following types:
enum IRStmtType
{
  SIMPLE,                       // Anything not covered below.
  COMPOUND,                     // A block of statements.
  LOOP,                         // Any type of top-tested, structured loop.
  END_TESTED_LOOP,              // Any type of end-tested, structured loop.
  STRUCT_TWOWAY_CONDITIONAL,    // Structured if-then-else.
  STRUCT_MULTIWAY_CONDITIONAL,  // Structured switch statement.
  USTRUCT_TWOWAY_CONDITIONAL_T, // Unstructured branch (on true).
  USTRUCT_TWOWAY_CONDITIONAL_F, // Unstructured branch (on false).
  USTRUCT_MULTIWAY_CONDITIONAL, // Unstructured multiway branch
                                //  (e.g., computed goto in Fortran or
                                //  jump tables in low-level/assembly
                                //  languages).
  RETURN,                       // Return statement.
  BREAK,                        // Break statement.
  LOOP_CONTINUE,                // Loop continuation statement.
  ALTERNATE_PROC_ENTRY,         // Alternate entry point (e.g., Fortran)
  UNCONDITIONAL_JUMP,           // GOTO in HLL, or unconditional direct
                                //   jump in low-level/assembly languages.
  UNCONDITIONAL_JUMP_I,         // Assigned GOTO in HLL, or unconditional
                                //   indirect jump in low-level/assembly
                                //   languages.
  NONE
};


class EdgeInfo;

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------

// The IRInterface abstract base class gives a set of methods for manipulating
// a program.  This is the primary interface to the underlying intermediate
// representation.
class IRInterface {
 public:
  IRInterface() { }
  virtual ~IRInterface() { }

  //--------------------------------------------------------
  // Procedures and call sites
  //--------------------------------------------------------

  // Given a procedure, return its IRProcType.
  virtual IRProcType GetProcType(ProcHandle h) = 0;

  // Given a ProcHandle, return an IRStmtIterator* for the
  // procedure. The user must free the iterator's memory via delete.
  virtual IRStmtIterator *ProcBody(ProcHandle h) = 0;

  // Get IRCallsiteIterator* for a statement. The user must free the
  // iterator's memory via delete.
  virtual IRCallsiteIterator *GetCallsites(StmtHandle h) = 0;

  // Get IRCallsiteIterator* for a statement. The user must free the
  // iterator's memory via delete.
  virtual IRCallsiteParamIterator *GetCallsiteParams(ExprHandle h) = 0;

  virtual bool IsParamProcRef(ExprHandle h) = 0;

  // Given an expression representing a callsite, is this an
  // invocation through a procedure parameter.
  virtual bool IsCallThruProcParam(ExprHandle h) = 0;


  //--------------------------------------------------------
  // Statements: General
  //--------------------------------------------------------

  // Given a statement, return its IRStmtType.
  virtual IRStmtType GetStmtType(StmtHandle h) = 0;

  // Given a statement, return a label (or NULL if
  // there is no label associated with the statement).
  virtual StmtLabel GetLabel(StmtHandle h) = 0;

  // Given a compound statement, return an IRStmtIterator* for the
  // statements.  The user must free the iterator's memory via delete.
  // A compound is a list of statements.
  virtual IRStmtIterator *GetFirstInCompound(StmtHandle h) = 0;

  //--------------------------------------------------------
  // Loops
  //--------------------------------------------------------

  // Given a loop statement, return an IRStmtIterator* for the loop body.
  // The user must free the iterator's memory via delete.
  virtual IRStmtIterator *LoopBody(StmtHandle h) = 0;

  // Given a loop statement, return the loop header statement.  This
  // would be the initialization statement in a C 'for' loop, for example.
  virtual StmtHandle LoopHeader(StmtHandle h) = 0;

  // Given a loop statement, return the increment statement.
  virtual StmtHandle GetLoopIncrement(StmtHandle h) = 0;

  // Given a loop statement, return:
  //
  // True: If the number of loop iterations is defined
  // at loop entry (i.e. Fortran semantics).  This causes the CFG builder
  // to add the loop statement representative to the header node so that
  // definitions from inside the loop don't reach the condition and increment
  // specifications in the loop statement.
  //
  // False: If the number of iterations is not defined at
  // entry (i.e. C semantics), we add the loop statement to a node that
  // is inside the loop in the CFG so definitions inside the loop will
  // reach uses in the conditional test. For C style semantics, the
  // increment itself may be a separate statement. if so, it will appear
  // explicitly at the bottom of the loop.
  virtual bool LoopIterationsDefinedAtEntry(StmtHandle h) = 0;

  //--------------------------------------------------------
  // Invariant: a two-way conditional or a multi-way conditional MUST provide
  // provide either a target, or a target label
  //--------------------------------------------------------

  //--------------------------------------------------------
  // Structured two-way conditionals
  //
  // Note: An important pre-condition for structured conditionals is
  // that chains of else-ifs must be represented as nested elses.  For
  // example, this Matlab statement:
  //   if (c1)
  //     s1;
  //   elseif (c2)
  //     s2;
  //   else
  //     s3;
  //   end;
  //
  // would need be represented by the underlying IR as:
  //   if (c1)
  //     s1;
  //   else
  //     if (c2)
  //       s2;
  //     else
  //       s3;
  //     end;
  //   end;
  //--------------------------------------------------------

  // Given a structured two-way conditional statement, return an
  // IRStmtIterator* for the "true" part (i.e., the statements under
  // the "if" clause). The user must free the iterator's memory via
  // delete.
  virtual IRStmtIterator *TrueBody(StmtHandle h) = 0;

  // Given a structured two-way conditional statement, return an
  // IRStmtIterator* for the "else" part (i.e., the statements under
  // the "else" clause). The user must free the iterator's memory via
  // delete.
  virtual IRStmtIterator *ElseBody(StmtHandle h) = 0;

  //--------------------------------------------------------
  // Structured multiway conditionals
  //--------------------------------------------------------

  // Given a structured multi-way branch, return the number of cases.
  // The count does not include the default/catchall case.
  virtual int NumMultiCases(StmtHandle h) = 0;

  // Given a structured multi-way branch, return an IRStmtIterator* for
  // the body corresponding to target 'bodyIndex'. The n targets are
  // indexed [0..n-1].  The user must free the iterator's memory via delete.
  virtual IRStmtIterator *MultiBody(StmtHandle h, int bodyIndex) = 0;

  // Given a structured multi-way branch, return true if the cases have
  // implied break semantics.  For example, this method would return false
  // for C since one case will fall-through to the next if there is no
  // explicit break statement.  Matlab, on the other hand, implicitly exits
  // the switch statement once a particular case has executed, so this
  // method would return true.
  virtual bool IsBreakImplied(StmtHandle multicond) = 0;

  // Given a structured multi-way branch, return an IRStmtIterator*
  // for the body corresponding to default/catchall case.  The user
  // must free the iterator's memory via delete.
  virtual IRStmtIterator * GetMultiCatchall (StmtHandle h) = 0;

  //--------------------------------------------------------
  // Unstructured two-way conditionals:
  //--------------------------------------------------------

  // Given an unstructured two-way branch, return the label of the
  // target statement.  The second parameter is currently unused.
  virtual StmtLabel  GetTargetLabel(StmtHandle h, int n) = 0;

  //--------------------------------------------------------
  // Unstructured multi-way conditionals
  // FIXME: Review all of the multi-way stuff.
  //--------------------------------------------------------

  // Given an unstructured multi-way branch, return the number of targets.
  // The count does not include the optional default/catchall case.
  virtual int NumUMultiTargets(StmtHandle h) = 0;

  // Given an unstructured multi-way branch, return the label of the target
  // statement at 'targetIndex'. The n targets are indexed [0..n-1].
  virtual StmtLabel GetUMultiTargetLabel(StmtHandle h, int targetIndex) = 0;

  // Given an unstructured multi-way branch, return label of the target
  // corresponding to the optional default/catchall case.  Return 0
  // if there is no default target.
  virtual StmtLabel GetUMultiCatchallLabel(StmtHandle h) = 0;

  //--------------------------------------------------------
  // Special, for assembly-language level instructions only.
  // These are necessary because there are some intricacies involved
  // in building a CFG for an instruction set which has delayed branches,
  // and in particular, allows branches within branch delay slots.
  //--------------------------------------------------------

  // Given a statement, return true if it issues in parallel with its
  // successor.  This would be used, for example, when the underlying IR
  // is a low-level/assembly-level language for a VLIW or superscalar
  // instruction set. The default implementation (which is appropriate
  // for most IR's) is to return false.
  virtual bool ParallelWithSuccessor(StmtHandle h) { return false; }

  // Given an unstructured branch/jump statement, return the number
  // of delay slots. Again, this would be used when the underlying IR
  // is a low-level/assembly-level language for a VLIW or superscalar
  // instruction set. The default implementation (which is appropriate
  // for most IR's) is to return 0.
  virtual int NumberOfDelaySlots(StmtHandle h) { return 0; }


  //--------------------------------------------------------
  // Obtain uses and defs
  //--------------------------------------------------------

  // Given a statement, return an IRUseDefIterator* (which is used by the
  // client to enumerate all the variables referenced by the statement).
  // The user must free the iterator's memory via delete.
  virtual IRUseDefIterator *GetUses(StmtHandle h) = 0;

  // Given a statement, return an IRUseDefIterator* (which is used by the
  // client to enumerate all the variables defined by the statement).
  // The user must free the iterator's memory via delete.
  virtual IRUseDefIterator *GetDefs(StmtHandle h) = 0;

  //--------------------------------------------------------
  // Symbol Handles
  //--------------------------------------------------------

  // FIXME
  virtual SymHandle GetProcSymHandle(ProcHandle h) = 0;

  // Given an ExprHandle containing a use or def (including a
  // callsite), return the SymHandle.  The SymHandle is mapped to a
  // symbol table entry for the variable or callsite.
  //virtual SymHandle GetSymHandle(LeafHandle vh) = 0; FIXME
  virtual SymHandle GetSymHandle(ExprHandle h) = 0; // GetExprSymHandle

  // Given a SymHandle, return the textual name.
  virtual const char *GetSymNameFromSymHandle(SymHandle sh) = 0;

  //--------------------------------------------------------
  // Debugging
  //--------------------------------------------------------

  // Given a LeafHandle, pretty-print it to the output stream os.
  // The default implementation does nothing.
  virtual void PrintLeaf(LeafHandle vh, std::ostream & os) { }

  // Given a statement, pretty-print it to the output stream os.
  // The default implementation does nothing.
  virtual void Dump(StmtHandle stmt, std::ostream& os) { }

  //--------------------------------------------------------
  // FIXME: the procedures below are of undetermined utility at the moment.
  //--------------------------------------------------------

  // Given a loop statement, return the loop condition expression.
  // This is the expression that tests for loop termination.
  virtual ExprHandle GetLoopCondition(StmtHandle h) = 0;

  // DQ (11/27/2005): I think this is not used.  Most locations (all but SgDoWhileStmt)
  // represent the condition as a SgStatement (especially true now with the current
  // modifications (required by C and C++ grammar specification)).
  // Given an unstructured two-way branch, return the branch condition expression.
  // virtual ExprHandle GetCondition(StmtHandle h) = 0;
  // virtual StmtHandle GetCondition(StmtHandle h) = 0;

  // Given an unstructured multi-way branch, return the condition
  // expression corresponding to target 'targetIndex'. The n targets
  // are indexed [0..n-1].
  virtual ExprHandle GetUMultiCondition(StmtHandle h, int targetIndex) = 0; // multiway target condition

  // Given a structured multi-way branch, return the condition
  // expression corresponding to target 'bodyIndex'. The n targets are
  // indexed [0..n-1].
  virtual ExprHandle GetSMultiCondition(StmtHandle h, int bodyIndex) = 0; //condition for multi body

  // Given a structured multi-way branch, return the switch/selector
  // expression.
  virtual ExprHandle GetMultiExpr(StmtHandle h) = 0; //multi-way beginning expression
};

// FIXME: Used from CFG::ltnode
//const char *IRGetSymNameFromLeafHandle(LeafHandle vh);

#endif // IRInterface_h