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&hl
fr
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);