LiveCheck.xcc

Benoit Boissinot (Benoit.Boissinotens-lyon.fr). Benoit Dupont de Dinechin (Benoit.Dupont-de-Dinechinst.com). Sebastian Hack (hacksebgmail.com). Fabrice Rastello (Fabrice.Rastelloens-lyon.fr).

Copyright 2007 - 2008 STMicroelectronics. Copyright 2007 - 2008 INRIA Rhone-Alpes.

This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.

This module implements the "fast liveness checking" method published in CGO 2008. Benoit Boissinot, Benoit Dupont-de-Dinechin, Daniel Grund, Sebastian Hack, and Fabrice Rastello. Fast Liveness Checking for SSA-Form Programs. International Symposium on Code Generation and Optimization (CGO'08). http://perso.ens-lyon.fr/fabrice.rastello/Biblio_Perso/Articles/CGO2008.pdf

LiveCheck_make requires the dominance. It precomputes some sets that only depend on the structure of the CFG. In practice, if the CFG is modified, or if basicBlock_INDEX is modified those sets have to be recomputed. Then using those precomputed sets, checking if a Variable (it must be an SSA variable!) is live{in/out} of a basicBlock/instruction, using either the mplex or the copy mode (this mode defines the semantic of a phi function. See below) can be done in O(#uses). The liveness check requires the def-use chains to be updated. The liveness check at operation granularity requires Operation_ORDERING to be updated. Notice that checking if a variable is livein of a phi will generate an exception failure.

LiveCheck_LIVENESS— If not zero, copy live classes from Liveness. 0 => use LiveCheck, 1 => copy from Liveness, 2 => both for debug.
#if ECL_OPTIMIZE
//#define LiveCheck_LIVENESS 0
#endif//ECL_OPTIMIZE
#ifndef LiveCheck_LIVENESS
extern int LiveCheck_LIVENESS;
#endif//LiveCheck_LIVENESS
LiveCheckMode— Enumerates the LiveCheck modes.

Different modes are possible: http//docs.google.com/Doc?dociddc6bn3dg_0fvdttj&hlfr Copy a use of a phi is placed at the end of the predecessor block the def of a phi is placed at the beginning of the block Mplex: The phi acts as a multiplexer in the multiplexing region: a use of a phi is placed on the incomming edge the def of a phi is placed just before the entry of the block. Mixed: This mode is used when some kind of PHI virtualisation is in place. At the begining of the out-of SSA phase the mode is COPY, but while PHI arguments are processed, they are added to the working sets.

typedef enum {
  LiveCheckMode_Copy = 0x1,     // Liveness in copy mode.
  LiveCheckMode_Mplex = 0x2,    // Liveness in mplex mode.
  LiveCheckMode_Mixed = 0x4,    // Liveness in mixed mode.
} LiveCheckMode;
typedef uint8_t short_LiveCheckMode;
LiveCheck— Liveness check.
struct LiveCheck_;
LiveCheck_make— Liveness check precomputation.
LiveCheck
LiveCheck_make(Memory parent, Dominance dominance, Liveness liveness);
LiveCheck_memory— This LiveCheck Memory.
Memory
LiveCheck_memory(const_LiveCheck this);
LiveCheck_isSSALiveInBasicBlock— Liveness check.
#define LiveCheck_isSSALiveInBasicBlock_copy(this, Q, variable) \
  LiveCheck_isSSALiveInBasicBlock(this, Q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveInBasicBlock_mplex(this, Q, variable) \
  LiveCheck_isSSALiveInBasicBlock(this, Q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveInBasicBlock_mixed(this, Q, variable) \
  LiveCheck_isSSALiveInBasicBlock(this, Q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveInBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode);

LiveCheck_isSetLiveInBasicBlock -- Liveness check using livesets.

#define LiveCheck_isSetLiveInBasicBlock_copy(this, Q, variable) \
  LiveCheck_isSetLiveInBasicBlock(this, Q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveInBasicBlock_mplex(this, Q, variable) \
  LiveCheck_isSetLiveInBasicBlock(this, Q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveInBasicBlock_mixed(this, Q, variable) \
  LiveCheck_isSetLiveInBasicBlock(this, Q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveInBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode);
// we check for livein at basic block Q
// mode can be MPLEX or COPY (see above)

LiveCheck_isLiveInBasicBlock --

static inline bool
LiveCheck_isLiveInBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode)
{
  bool liveincheck = false;
  bool liveinset = false;
  if (LiveCheck_LIVENESS==0 || LiveCheck_LIVENESS==2)
    liveincheck = LiveCheck_isSSALiveInBasicBlock(this, Q, variable, mode);
  if (LiveCheck_LIVENESS>0)
    liveinset = LiveCheck_isSetLiveInBasicBlock(this, Q , variable, mode);
  Except_CHECK(LiveCheck_LIVENESS!=2 || (liveinset == liveincheck));
  return liveincheck || liveinset;
}
LiveCheck_isSSALiveOutBasicBlock— Liveness check.
#define LiveCheck_isSSALiveOutBasicBlock_copy(this, Q, variable) \
  LiveCheck_isSSALiveOutBasicBlock(this, Q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveOutBasicBlock_mplex(this, Q, variable) \
  LiveCheck_isSSALiveOutBasicBlock(this, Q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveOutBasicBlock_mixed(this, Q, variable) \
  LiveCheck_isSSALiveOutBasicBlock(this, Q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveOutBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode);

LiveCheck_isSetLiveOutBasicBlock -- LiveCheck check using livesets.

#define LiveCheck_isSetLiveOutBasicBlock_copy(this, Q, variable) \
  LiveCheck_isSetLiveOutBasicBlock(this, Q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveOutBasicBlock_mplex(this, Q, variable) \
  LiveCheck_isSetLiveOutBasicBlock(this, Q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveOutBasicBlock_mixed(this, Q, variable) \
  LiveCheck_isSetLiveOutBasicBlock(this, Q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveOutBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode);
// we check for liveout at basic block Q
// mode can be MPLEX or COPY (see above)

LiveCheck_isLiveOutBasicBlock --

static inline bool
LiveCheck_isLiveOutBasicBlock(LiveCheck this, BasicBlock Q, Variable variable, uint32_t mode)
{
  bool liveoutcheck = false;
  bool liveoutset = false;
  if (LiveCheck_LIVENESS==0 || LiveCheck_LIVENESS==2)
    liveoutcheck = LiveCheck_isSSALiveOutBasicBlock(this, Q, variable, mode);
  if (LiveCheck_LIVENESS>0)
    liveoutset = LiveCheck_isSetLiveOutBasicBlock(this, Q , variable, mode);
  Except_CHECK(LiveCheck_LIVENESS!=2 || (liveoutset == liveoutcheck));
  return liveoutcheck || liveoutset;
}
LiveCheck_isSSALiveInOperation— Liveness check.
#define LiveCheck_isSSALiveInOperation_copy(this, q, variable) \
  LiveCheck_isSSALiveInOperation(this, q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveInOperation_mplex(this, q, variable) \
  LiveCheck_isSSALiveInOperation(this, q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveInOperation_mixed(this, q, variable) \
  LiveCheck_isSSALiveInOperation(this, q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveInOperation(LiveCheck this, Operation q, Variable variable, uint32_t mode);

LiveCheck_isSetLiveInOperation -- LiveCheck check using livesets.

#define LiveCheck_isSetLiveInOperation_copy(this, q, variable) \
  LiveCheck_isSetLiveInOperation(this, q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveInOperation_mplex(this, q, variable) \
  LiveCheck_isSetLiveInOperation(this, q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveInOperation_mixed(this, q, variable) \
  LiveCheck_isSetLiveInOperation(this, q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveInOperation(LiveCheck this, Operation q, Variable variable, uint32_t mode);
LiveCheck_isSSALiveOutOperation— Liveness check.
#define LiveCheck_isSSALiveOutOperation_copy(this, q, variable) \
  LiveCheck_isSSALiveOutOperation(this, q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveOutOperation_mplex(this, q, variable) \
  LiveCheck_isSSALiveOutOperation(this, q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveOutOperation_mixed(this, q, variable) \
  LiveCheck_isSSALiveOutOperation(this, q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveOutOperation(LiveCheck this, Operation q, Variable variable, uint32_t mode);

LiveCheck_isSetLiveOutOperation -- LiveCheck check using livesets.

#define LiveCheck_isSetLiveOutOperation_copy(this, q, variable) \
  LiveCheck_isSetLiveOutOperation(this, q, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveOutOperation_mplex(this, q, variable) \
  LiveCheck_isSetLiveOutOperation(this, q, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveOutOperation_mixed(this, q, variable) \
  LiveCheck_isSetLiveOutOperation(this, q, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveOutOperation(LiveCheck this, Operation q, Variable variable, uint32_t mode);

LiveCheck_isSSALiveInOrdering -- Liveness check.

#define LiveCheck_isSSALiveInOrdering_copy(this, Q, ordering, variable) \
  LiveCheck_isSSALiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveInOrdering_mplex(this, Q, ordering, variable) \
  LiveCheck_isSSALiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveInOrdering_mixed(this, Q, ordering, variable) \
  LiveCheck_isSSALiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveInOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode);

LiveCheck_isSetLiveInOrdering -- LiveCheck check using livesets.

#define LiveCheck_isSetLiveInOrdering_copy(this, Q, ordering, variable) \
  LiveCheck_isSetLiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveInOrdering_mplex(this, Q, ordering, variable) \
  LiveCheck_isSetLiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveInOrdering_mixed(this, Q, ordering, variable) \
  LiveCheck_isSetLiveInOrdering(this, Q, ordering, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveInOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode);

LiveCheck_isLiveInOrdering --

static inline bool
LiveCheck_isLiveInOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode)
{
  bool liveincheck = false;
  bool liveinset = false;
  if (LiveCheck_LIVENESS==0 || LiveCheck_LIVENESS==2)
    liveincheck = LiveCheck_isSSALiveInOrdering(this, Q, ordering, variable, mode);
  if (LiveCheck_LIVENESS>0)
    liveinset = LiveCheck_isSetLiveInOrdering(this, Q , ordering, variable, mode);
  Except_CHECK(LiveCheck_LIVENESS!=2 || (liveinset == liveincheck));
  return liveincheck || liveinset;
}

LiveCheck_isSSALiveOutOrdering -- Liveness check.

#define LiveCheck_isSSALiveOutOrdering_copy(this, Q, ordering, variable) \
  LiveCheck_isSSALiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Copy)
#define LiveCheck_isSSALiveOutOrdering_mplex(this, Q, ordering, variable) \
  LiveCheck_isSSALiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSSALiveOutOrdering_mixed(this, Q, ordering, variable) \
  LiveCheck_isSSALiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSSALiveOutOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode);

LiveCheck_isSetLiveOutOrdering -- LiveCheck check using livesets.

#define LiveCheck_isSetLiveOutOrdering_copy(this, Q, ordering, variable) \
  LiveCheck_isSetLiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Copy)
#define LiveCheck_isSetLiveOutOrdering_mplex(this, Q, ordering, variable) \
  LiveCheck_isSetLiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Mplex)
#define LiveCheck_isSetLiveOutOrdering_mixed(this, Q, ordering, variable) \
  LiveCheck_isSetLiveOutOrdering(this, Q, ordering, variable, LiveCheckMode_Mixed)
bool
LiveCheck_isSetLiveOutOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode);

LiveCheck_isLiveOutOrdering --

static inline bool
LiveCheck_isLiveOutOrdering(LiveCheck this, BasicBlock Q, int32_t ordering, Variable variable, uint32_t mode)
{
  bool liveoutcheck = false;
  bool liveoutset = false;
  if (LiveCheck_LIVENESS==0 || LiveCheck_LIVENESS==2)
    liveoutcheck = LiveCheck_isSSALiveOutOrdering(this, Q, ordering, variable, mode);
  if (LiveCheck_LIVENESS>0)
    liveoutset = LiveCheck_isSetLiveOutOrdering(this, Q , ordering, variable, mode);
  Except_CHECK(LiveCheck_LIVENESS!=2 || (liveoutset == liveoutcheck));
  return liveoutcheck || liveoutset;
}

LiveCheck_prettyCFG -- PrettyPrint in dotty format of the CFG.

void
LiveCheck_prettyCFG(LiveCheck this, FILE *file);

LiveCheck_dumpCFG -- DumpCFG into a functionname.dotty file

void
LiveCheck_dumpCFG(LiveCheck this);