#include "ident.h"
#include "interval_analysis.h"
#include "irarch.h"
-#include "ircgcons.h"
#include "ircgopt.h"
#include "irconsconfirm.h"
#include "ircons.h"
/* states */
-/** The state of the interprocedural view.
- *
- * This value indicates the state of the interprocedural view.
- */
-typedef enum {
- ip_view_no, /**< The interprocedural view is not constructed. There are no
- view specific nodes (EndReg, Filter, Break ...) in any graph. */
- ip_view_valid, /**< The interprocedural view is valid. */
- ip_view_invalid /**< The interprocedural view is invalid. Specific nodes are
- all still in the representation, but the graph is no more complete. */
-} ip_view_state;
-
/**
* This function is called, whenever a local variable is used before definition
*
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Construction and removal of interprocedural representation
- * (explicit interprocedural dependencies).
- * @author Hubert Schmid
- * @date 09.06.2002
- * @version $Id$
- */
-#ifndef FIRM_IR_IRCGCONS_H
-#define FIRM_IR_IRCGCONS_H
-
-#ifdef INTERPROCEDURAL_VIEW
-
-#include "firm_types.h"
-#include "begin.h"
-
-/** Return the current state of the interprocedural view. */
-FIRM_API ip_view_state get_irp_ip_view_state(void);
-/** Set the state of the interprocedural view to invalid. */
-FIRM_API void set_irp_ip_view_invalid(void);
-
-/** Construction of the interprocedural view.
- *
- * Construction of the interprocedural view. A prior analysis must have set
- * all possible callees in the corresponding fields of Call nodes. Sets
- * ip_view_valid in irp.
- *
- * @arg free_methods_arr: An array of all free methods, i.e., methods that
- * are external visible. These methods get an 'Unknown'
- * caller.
- * @arg arr_len The number of free methods. */
-FIRM_API void cg_construct(int arr_len, ir_entity *free_methods_arr[]);
-
-
-/** Deconstruction of the interprocedural view. Reduces memory consumption of
- the ir. Sets ip_view_no in irp. */
-FIRM_API void cg_destruct(void);
-
-#include "end.h"
-
-#endif
-
-#endif
* is mature. As other constructors calls optimization and vrfy for the
* block. If one of the predecessors is Unknown (as it has to be filled in
* later) optimizations are skipped. This is necessary to
- * construct Blocks in loops. Leaving Unknown in the Block after finishing
- * the construction may have strange effects, especially for interprocedural
- * representation and analysis.
+ * construct Blocks in loops.
*
*
* CONTROL FLOW OPERATIONS
* of in's of current_block. This is not checked by the library!
* If one of the predecessors is Unknown (as it has to be filled in
* later) optimizations are skipped. This is necessary to
- * construct Phi nodes in loops. Leaving Unknown in the Phi after finishing
- * the construction may have strange effects, especially for interprocedural
- * representation and analysis.
+ * construct Phi nodes in loops.
*
* Parameter
* arity number of predecessors
*/
FIRM_API ir_node *new_rd_IJmp(dbg_info *db, ir_node *block, ir_node *tgt);
-/** Constructor for a Break node.
- *
- * Break represents control flow to a single control successor just as Jmp.
- * The blocks separated by a break may not be concatenated by an optimization.
- * It is used for the interprocedural representation where blocks are parted
- * behind Call nodes to represent the control flow to called procedures.
- *
- * @param *db A pointer for debug information.
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_rd_Break(dbg_info *db, ir_node *block);
-
/** Constructor for a Cond node.
*
* If c is mode_b represents a conditional branch (if/else). If c is
*/
FIRM_API ir_node *new_rd_Unknown(dbg_info *db, ir_graph *irg, ir_mode *m);
-/** Constructor for a CallBegin node.
- *
- * CallBegin represents control flow depending of the pointer value
- * representing the called method to the called methods. The
- * constructor copies the method pointer input from the passed Call
- * node.
- *
- * @param *db A pointer for debug information.
- * @param *block The block the node belong to.
- * @param *ptr pointer to the called function
- * @param *call associated call operation
- */
-FIRM_API ir_node *new_rd_CallBegin(dbg_info *db, ir_node *block, ir_node *ptr,
- ir_node *call);
-
-/** Constructor for a EndReg node.
- *
- * Used to represent regular procedure end in interprocedual view.
- *
- * @param *db A pointer for debug information.
- * @param *irg The IR graph the node belong to.
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_rd_EndReg(dbg_info *db, ir_graph *irg, ir_node *block);
-
-/** Constructor for a EndExcept node.
- *
- * Used to represent exceptional procedure end in interprocedural view.
- *
- * @param *db A pointer for debug information.
- * @param *irg The IR graph the node belong to.
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_rd_EndExcept(dbg_info *db, ir_graph *irg, ir_node *block);
-
-/** Constructor for a Filter node.
- *
- * Adds the node to the block in current_ir_block. Filter is a node
- * with two views used to construct the interprocedural view. In
- * intraprocedural view its semantics are identical to the Proj node.
- * In interprocedural view the Filter performs the Phi operation on
- * method parameters or results. Other than a Phi a Filter node may
- * not be removed if it has only a single input.
- *
- * The constructor builds the Filter in intraprocedural view.
- *
- * @param *db A pointer for debug information.
- * @param *block The block the node belong to.
- * @param *arg The tuple value to project from.
- * @param *mode The mode of the projected value.
- * @param proj The position in the tuple to project from.
- */
-FIRM_API ir_node *new_rd_Filter(dbg_info *db,ir_node *block, ir_node *arg,
- ir_mode *mode, long proj);
-
/** Constructor for a Mux node.
*
* @param *db A pointer for debug information.
*/
FIRM_API ir_node *new_r_Unknown(ir_graph *irg, ir_mode *m);
-/** Constructor for a CallBegin node.
- *
- * CallBegin represents control flow depending of the pointer value
- * representing the called method to the called methods. The
- * constructor copies the method pointer input from the passed Call
- * node.
- *
- * @param *block The block the node belong to.
- * @param *ptr pointer to the called function
- * @param *call associated call operation
- */
-FIRM_API ir_node *new_r_CallBegin(ir_node *block, ir_node *ptr, ir_node *call);
-
-/** Constructor for a EndReg node.
- *
- * Used to represent regular procedure end in interprocedual view.
- *
- * @param *irg The IR graph the node belong to.
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_r_EndReg(ir_graph *irg, ir_node *block);
-
-/** Constructor for a EndExcept node.
- *
- * Used to represent exceptional procedure end in interprocedural view.
- *
- * @param *irg The IR graph the node belong to.
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_r_EndExcept(ir_graph *irg, ir_node *block);
-
-/** Constructor for a Break node.
- *
- * Break represents control flow to a single control successor just as Jmp.
- * The blocks separated by a break may not be concatenated by an optimization.
- * It is used for the interprocedural representation where blocks are parted
- * behind Call nodes to represent the control flow to called procedures.
- *
- * @param *block The block the node belong to.
- */
-FIRM_API ir_node *new_r_Break(ir_node *block);
-
-/** Constructor for a Filter node.
- *
- * Constructor for a Filter node. Adds the node to the block in current_ir_block.
- * Filter is a node with two views used to construct the interprocedural view.
- * In intraprocedural view its semantics are identical to the Proj node.
- * In interprocedural view the Filter performs the Phi operation on method
- * parameters or results. Other than a Phi a Filter node may not be removed
- * if it has only a single input.
- *
- * The constructor builds the Filter in intraprocedural view.
- *
- * @param *block The block the node belong to.
- * @param *arg The tuple value to project from.
- * @param *mode The mode of the projected value.
- * @param proj The position in the tuple to project from.
- */
-FIRM_API ir_node *new_r_Filter(ir_node *block, ir_node *arg, ir_mode *mode,
- long proj);
-
/** Constructor for a NoMem node.
*
* Returns the unique NoMem node of the graph. The same as
*/
FIRM_API ir_node *new_d_Unknown(dbg_info *db, ir_mode *m);
-/** Constructor for a CallBegin node.
- *
- * CallBegin represents control flow depending of the pointer value
- * representing the called method to the called methods. The
- * constructor copies the method pointer input from the passed Call
- * node.Adds the node to the block in current_ir_block.
- *
- * @param *db A pointer for debug information.
- * @param *ptr pointer to the called function
- * @param *call associated call operation
- */
-FIRM_API ir_node *new_d_CallBegin(dbg_info *db, ir_node *ptr, ir_node *call);
-
-/** Constructor for an EndReg node.
- *
- *Adds the node to the block in current_ir_block.
- *
- * @param *db A pointer for debug information.
- */
-FIRM_API ir_node *new_d_EndReg(dbg_info *db);
-
-/** Constructor for an EndExcept node.
- *
- * Used to represent regular procedure end in interprocedual view.
- * Adds the node to the block in current_ir_block.
- *
- * @param *db A pointer for debug information.
- */
-FIRM_API ir_node *new_d_EndExcept(dbg_info *db);
-
-/** Constructor for a Break node.
- *
- * Used to represent exceptional procedure end in interprocedural view.
- * Adds the node to the block in current_ir_block.
- *
- * Break represents control flow to a single control successor just as Jmp.
- * The blocks separated by a break may not be concatenated by an optimization.
- * It is used for the interprocedural representation where blocks are parted
- * behind Call nodes to represent the control flow to called procedures.
- *
- * @param *db A pointer for debug information.
- */
-FIRM_API ir_node *new_d_Break(dbg_info *db);
-
-/** Constructor for a Filter node.
- *
- * Constructor for a Filter node. Adds the node to the block in
- * current_ir_block. Filter is a node with two views used to
- * construct the interprocedural view. In intraprocedural view its
- * semantics are identical to the Proj node. In interprocedural view
- * the Filter performs the Phi operation on method parameters or
- * results. Other than a Phi a Filter node may not be removed if it
- * has only a single input.
- *
- * The constructor builds the Filter in intraprocedural view.
- *
- * @param *db A pointer for debug information.
- * @param *arg The tuple value to project from.
- * @param *mode The mode of the projected value.
- * @param proj The position in the tuple to project from.
- */
-FIRM_API ir_node *new_d_Filter(dbg_info *db, ir_node *arg, ir_mode *mode,
- long proj);
-
/** Constructor for a Mux node.
*
* @param *db A pointer for debug information.
*/
FIRM_API ir_node *new_End(void);
-/** Constructor for an EndReg node.
- *
- * Used to represent regular procedure end in interprocedual view.
- * Adds the node to the block in current_ir_block.
- */
-FIRM_API ir_node *new_EndReg(void);
-
-/** Constructor for an EndExpcept node.
- *
- * Used to represent exceptional procedure end in interprocedural view.
- * Adds the node to the block in current_ir_block.
- */
-FIRM_API ir_node *new_EndExcept(void);
-
/** Constructor for a Jump node.
*
* Adds the node to the block in current_ir_block.
*/
FIRM_API ir_node *new_IJmp(ir_node *tgt);
-/** Constructor for a Break node.
- * Break represents control flow to a single control successor just as Jmp.
- * The blocks separated by a break may not be concatenated by an optimization.
- * It is used for the interprocedural representation where blocks are parted
- * behind Call nodes to represent the control flow to called procedures.
- * Adds the node to the block in current_ir_block.
- */
-FIRM_API ir_node *new_Break(void);
-
/** Constructor for a Cond node.
*
* If c is mode_b represents a conditional branch (if/else). If c is
FIRM_API ir_node *new_Builtin(ir_node *store, int arity, ir_node *in[],
ir_builtin_kind kind, ir_type *tp);
-/** Constructor for a CallBegin node.
- *
- * CallBegin represents control flow depending of the pointer value
- * representing the called method to the called methods. The
- * constructor copies the method pointer input from the passed Call
- * node. Adds the node to the block in current_ir_block.
- *
- * @param *ptr pointer to the called function
- * @param *call associated call operation
- */
-FIRM_API ir_node *new_CallBegin(ir_node *ptr, ir_node *call);
-
/** Constructor for a Add node.
*
* Adds the node to the block in current_ir_block.
*/
FIRM_API ir_node *new_Proj(ir_node *arg, ir_mode *mode, long proj);
-/** Constructor for a Filter node.
- *
- * Constructor for a Filter node. Adds the node to the block in current_ir_block.
- * Filter is a node with two views used to construct the interprocedural view.
- * In intraprocedural view its semantics are identical to the Proj node.
- * In interprocedural view the Filter performs the Phi operation on method
- * parameters or results. Other than a Phi a Filter node may not be removed
- * if it has only a single input.
- *
- * The constructor builds the Filter in intraprocedural view.
- *
- * @param *arg The tuple value to project from.
- * @param *mode The mode of the projected value.
- * @param proj The position in the tuple to project from.
- */
-FIRM_API ir_node *new_Filter(ir_node *arg, ir_mode *mode, long proj);
-
/** Constructor for a defaultProj node.
*
* Represents the default control flow of a Switch-Cond node.
* edges from constant to block are skipped. Vcg then layouts the graphs
* more compact, this makes them better readable. */
ir_dump_flag_consts_local = 1U << 4,
- /** if set node idx will be added to node labels */
+ /** if set node idx will be added to node labels */
ir_dump_flag_idx_label = 1U << 5,
/** if set node number will be added to node labels */
ir_dump_flag_number_label = 1U << 6,
/** if set dumps edges from blocks to their immediate dominator */
ir_dump_flag_dominance = 1U << 9,
/** If set the dumper dumps loop nodes and edges from these nodes to the
- * contained ir nodes. Nodes can be missing for interprocedural loops */
+ * contained ir nodes. */
ir_dump_flag_loops = 1U << 10,
/** if set (and backedge info is computed) dump backedges */
ir_dump_flag_back_edges = 1U << 11,
FIRM_API ir_graph *get_current_ir_graph(void);
FIRM_API void set_current_ir_graph(ir_graph *graph);
-#ifdef INTERPROCEDURAL_VIEW
-/** This flag indicate the current view. The behavior of some methods
- * (get_irn_*, set_irn_*) is influenced by this flag. */
-FIRM_API int get_interprocedural_view(void);
-FIRM_API void set_interprocedural_view(int state);
-#endif
-
/**
* Create a new ir graph to build ir for a procedure.
*
/** Sets the End node of an IR graph. */
FIRM_API void set_irg_end(ir_graph *irg, ir_node *node);
-/* The fields end_reg and end_except contain the end nodes of the
- interprocedural view. If the view is not constructed they contain
- the normal end node. */
-FIRM_API ir_node *get_irg_end_reg(const ir_graph *irg);
-FIRM_API void set_irg_end_reg(ir_graph *irg, ir_node *node);
-
-FIRM_API ir_node *get_irg_end_except(const ir_graph *irg);
-FIRM_API void set_irg_end_except(ir_graph *irg, ir_node *node);
-
/** Returns the node that represents the initial control flow of the given
* IR graph. */
FIRM_API ir_node *get_irg_initial_exec(const ir_graph *irg);
*
* Like irg_walk(), but walks over all reachable nodes in the ir
* graph, starting at the end operation. During the walk current_ir_graph
- * is set to irg. Does not use the link field. If interprocedural_view
- * is set, visits all reachable irgs.
+ * is set to irg. Does not use the link field.
*/
FIRM_API void irg_walk_graph(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env);
* graph, starting at the end operation. During the walk current_ir_graph
* is set to irg. Does not use the link field.
* This walker also follows additional dependency egdes.
- * interprocedural_view is not yet supported.
*/
FIRM_API void irg_walk_in_or_dep_graph(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env);
*
* This function executes irg_walk(end, pre, post, env) for all irgraphs in irprog.
* Sets current_ir_graph properly for each walk. Conserves current
- * current_ir_graph. In interprocedural view nodes can be visited several
- * times. Does not use the link field.
+ * current_ir_graph. Does not use the link field.
*/
FIRM_API void all_irg_walk(irg_walk_func *pre, irg_walk_func *post, void *env);
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Walks all irgs in interprocedural view.
- *
- * @param pre walker function, executed before the predecessor of a node are visited
- * @param post walker function, executed after the predecessor of a node are visited
- * @param env environment, passed to pre and post
- *
- * This function walks all irgs in interprocedural view.
- * Visits each node only once. Sets current_ir_graph properly. Does not use the link field.
- */
-FIRM_API void cg_walk(irg_walk_func *pre, irg_walk_func *post, void *env);
-#endif
-
/** Walks only over Block nodes in the graph.
*
* @param node the start node
* flag. It marks the node as visited before executing pre.
* The void *env can be used to pass status information between the
* pre and post functions. Does not use the link fields.
- * Walks only intraprocedural, even in interprocedural view.
*
* @param irg the irg graph
* @param pre walker function, executed before the predecessor of a node are visited
* flag. It marks the node as visited before executing pre.
* The void *env can be used to pass status information between the
* pre and post functions. Does not use the link fields.
- * Walks only intraprocedural, even in interprocedural view.
* This walker also follows dependency edges.
*
* @param irg the irg graph
* flag. It marks the node as visited before executing pre.
* The void *env can be used to pass status information between the
* pre and post functions. Does not use the link fields.
- * Walks only intraprocedural, even in interprocedural view.
*
* @param irg the irg graph
* @param pre walker function, executed before the predecessor of a node are visited
* Computes backedges in the control and data flow.
*
* @note
- * Only Block and Phi/Filter nodes can have incoming backedges.
+ * Only Block and Phi nodes can have incoming backedges.
* Constructs loops data structure: indicates loop nesting.
*/
#ifndef FIRM_ANA_IRLOOP_H
/*
* Backedge information.
*
- * Predecessors of Block, Phi and interprocedural Filter nodes can
- * have backedges. If loop information is computed, this
- * information is computed, too.
+ * Predecessors of Block and Phi nodes can have backedges.
+ * If loop information is computed, this information is computed, too.
* The backedge information can only be used if the graph is not in
* phase phase_building.
*/
/* ------------------------------------------------------------------- */
-#ifdef INTERPROCEDURAL_VIEW
-/** Returns true if the predecessor pos is a backedge in the interprocedural view. */
-FIRM_API int is_inter_backedge(ir_node *n, int pos);
-/** Returns true if the predecessor pos is a backedge in the intraprocedural view. */
-FIRM_API int is_intra_backedge(ir_node *n, int pos);
-#endif
/** Returns non-zero if the predecessor pos is a backedge. */
FIRM_API int is_backedge(ir_node *n, int pos);
/** Marks edge pos as a backedge. */
/* Constructing and destructing the loop/backedge information. */
/* ------------------------------------------------------------------- */
-/** Constructs backedge information and loop tree for a graph in intraprocedural view.
+/** Constructs backedge information and loop tree for a graph.
*
* The algorithm views the program representation as a pure graph.
* It assumes that only block and phi nodes may be loop headers.
*/
FIRM_API int construct_backedges(ir_graph *irg);
-#ifdef INTERPROCEDURAL_VIEW
-/** Constructs backedges for all irgs in interprocedural view.
- *
- * @see As construct_backedges(), but for interprocedural view.
- *
- * @remark
- * All loops in the graph will be marked as such, not only
- * realizeable loops and recursions in the program. E.g., if the
- * same funcion is called twice, there is a loop between the first
- * function return and the second call.
- *
- * @returns Maximal depth of loop tree.
- */
-FIRM_API int construct_ip_backedges(void);
-#endif
-
/**
* Construct Intra-procedural control flow loop tree for a IR-graph.
*
*/
FIRM_API void assure_cf_loop(ir_graph *irg);
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Construct Inter-procedural control flow loop tree.
- *
- * @see construct_cf_backedges() and construct_ip_backedges().
- */
-FIRM_API int construct_ip_cf_backedges(void);
-#endif
-
/**
* Removes all loop information.
* Resets all backedges. Works for any construction algorithm.
/**
* Assure that the entity usage flags have been computed for the given graph.
*
- * This is an intraprocedural analysis that computes the entity usage state
- * for all local variables.
+ * This analysis computes the entity usage state for all local variables.
*
* Note that this is a conservative estimation that by no Firm transformation
* can be invalidated, so it's only recomputed if manually triggered by calling
* @param node the IR-node
*/
FIRM_API int get_irn_arity (const ir_node *node);
-FIRM_API int get_irn_intra_arity(const ir_node *node);
-FIRM_API int get_irn_inter_arity(const ir_node *node);
/** Replaces the old in array by a new one that will contain the ins given in
the parameters. Conserves the block predecessor. It copies the array passed.
/**
* Get the n-th predecessor of a node.
* This function removes Id predecessors.
- * This function automatically handles intra- and interprocedural views.
*/
FIRM_API ir_node *get_irn_n(const ir_node *node, int n);
*/
FIRM_API void set_irn_dep(ir_node *node, int pos, ir_node *dep);
-
-/**
- * Get the n-th predecessor of a node in intraprocedural view.
- * Can be used always if it's know that node is not a split one.
- */
-FIRM_API ir_node *get_irn_intra_n(const ir_node *node, int n);
-
-/**
- * Get the n-th predecessor of a node in interprocedural view.
- */
-FIRM_API ir_node *get_irn_inter_n(const ir_node *node, int n);
-
/** Replace the n-th predecessor of a node with a new one. */
FIRM_API void set_irn_n(ir_node *node, int n, ir_node *in);
/**
FIRM_API void mark_Block_block_visited(ir_node *node);
FIRM_API int Block_block_visited(const ir_node *node);
-#ifdef INTERPROCEDURAL_VIEW
-/* Set and remove interprocedural predecessors. If the interprocedural
- * predecessors are removed, the node has the same predecessors in
- * both views.
- * @@@ Maybe better: arity is zero if no cg preds. */
-FIRM_API void set_Block_cg_cfgpred_arr(ir_node *node, int arity, ir_node *in[]);
-FIRM_API void set_Block_cg_cfgpred(ir_node *node, int pos, ir_node *pred);
-/* @@@ not supported */
-FIRM_API ir_node **get_Block_cg_cfgpred_arr(ir_node *node);
-/** Returns the number of interprocedural predecessors. 0 if none. */
-FIRM_API int get_Block_cg_n_cfgpreds(const ir_node *node);
-/** Return the interprocedural predecessor at position pos. */
-FIRM_API ir_node *get_Block_cg_cfgpred(const ir_node *node, int pos);
-/** Frees the memory allocated for interprocedural predecessors. */
-FIRM_API void remove_Block_cg_cfgpred_arr(ir_node *node);
-#endif
-
/** Returns the extended basic block a block belongs to. */
FIRM_API ir_extblk *get_Block_extbb(const ir_node *block);
/** Sets the extended basic block a block belongs to. */
/** Returns a human readable string for the ir_builtin_kind. */
FIRM_API const char *get_builtin_kind_name(ir_builtin_kind kind);
-/** Retrieve the call address of a CallBegin. */
-FIRM_API ir_node *get_CallBegin_ptr(const ir_node *node);
-/** Set the call address of a CallBegin. */
-FIRM_API void set_CallBegin_ptr(ir_node *node, ir_node *ptr);
-/** Retrieve the original Call node of a CallBegin. */
-FIRM_API ir_node *get_CallBegin_call(const ir_node *node);
-/** Set the original Call node of a CallBegin. */
-FIRM_API void set_CallBegin_call(ir_node *node, ir_node *call);
-
/* For unary and binary arithmetic operations the access to the
operands can be factored out. Left is the first, right the
second arithmetic value as listed in tech report 1999-44.
FIRM_API int is_Cast_downcast(ir_node *node);
-/** Returns true if n is a Phi or a Filter node in INTER-procedural view.
+/** Returns true if n is a Phi.
Returns false if irg is in phase phase_building and the Phi has zero
predecessors: it's a Phi0. */
FIRM_API int is_Phi(const ir_node *n);
/** Returns true if irg in phase phase_building and the Phi has zero
predecessors. It's a Phi0 then. */
FIRM_API int is_Phi0(const ir_node *n);
-/* These routines also work for Filter nodes in INTER-procedural view. */
FIRM_API ir_node **get_Phi_preds_arr(ir_node *node);
FIRM_API int get_Phi_n_preds(const ir_node *node);
FIRM_API ir_node *get_Phi_pred(const ir_node *node, int pos);
*/
FIRM_API void set_Phi_next(ir_node *phi, ir_node *next);
-FIRM_API ir_node *get_Filter_pred(const ir_node *node);
-FIRM_API void set_Filter_pred(ir_node *node, ir_node *pred);
-FIRM_API long get_Filter_proj(const ir_node *node);
-FIRM_API void set_Filter_proj(ir_node *node, long proj);
-/* set the interprocedural predecessors, ...d_arr uses current_ir_graph.
- * @@@ Maybe better: arity is zero if no cg preds. */
-FIRM_API void set_Filter_cg_pred_arr(ir_node *node, int arity, ir_node **in);
-FIRM_API void set_Filter_cg_pred(ir_node * node, int pos, ir_node * pred);
-FIRM_API int get_Filter_n_cg_preds(const ir_node *node);
-FIRM_API ir_node *get_Filter_cg_pred(const ir_node *node, int pos);
-
/** Return true if parameter is a memory operation.
*
* A memory operation is an operation that changes the
FIRM_API int is_Call(const ir_node *node);
/** Returns true if node is a Builtin node. */
FIRM_API int is_Builtin(const ir_node *node);
-/** Returns true if node is a CallBegin node. */
-FIRM_API int is_CallBegin(const ir_node *node);
/** Returns true if node is a Sel node. */
FIRM_API int is_Sel(const ir_node *node);
/** Returns true if node is a Mul node. */
FIRM_API int is_Break(const ir_node *node);
/** Returns true if a node is an instff node */
FIRM_API int is_InstOf(const ir_node *node);
-/** Returns true if node is a Proj node or a Filter node in INTRA-procedural view. */
+/** Returns true if node is a Proj node */
FIRM_API int is_Proj(const ir_node *node);
-/** Returns true if node is a Filter node. */
-FIRM_API int is_Filter(const ir_node *node);
/** Returns true if the operation manipulates control flow:
- Start, End, Jmp, Cond, Return, Raise, Bad, CallBegin, EndReg, EndExcept */
+ Start, End, Jmp, Cond, Return, Raise, Bad, EndReg, EndExcept */
FIRM_API int is_cfop(const ir_node *node);
-/** Returns true if the operation manipulates interprocedural control flow:
- CallBegin, EndReg, EndExcept */
+/** Returns true if the operation manipulates control flow: EndReg, EndExcept */
FIRM_API int is_ip_cfop(const ir_node *node);
/** Returns true if the operation can change the control flow because
of an exception: Call, Quot, DivMod, Div, Mod, Load, Store, Alloc,
/** The irop flags */
typedef enum {
- irop_flag_none = 0x00000000, /**< Nothing. */
- irop_flag_labeled = 0x00000001, /**< If set, output edge labels on in-edges in vcg graph. */
- irop_flag_commutative = 0x00000002, /**< This operation is commutative. */
- irop_flag_cfopcode = 0x00000004, /**< This operation is a control flow operation. */
- irop_flag_ip_cfopcode = 0x00000008, /**< This operation manipulates the interprocedural control flow. */
- irop_flag_fragile = 0x00000010, /**< Set if the operation can change the control flow because
- of an exception. */
- irop_flag_forking = 0x00000020, /**< Forking control flow at this operation. */
- irop_flag_highlevel = 0x00000040, /**< This operation is a pure high-level one and can be
- skipped in low-level optimizations. */
- irop_flag_constlike = 0x00000080, /**< This operation has no arguments and is some
- kind of a constant. */
- irop_flag_always_opt = 0x00000100, /**< This operation must always be optimized .*/
- irop_flag_keep = 0x00000200, /**< This operation can be kept in End's keep-alive list. */
- irop_flag_start_block = 0x00000400, /**< This operation is always placed in the Start block. */
- irop_flag_uses_memory = 0x00000800, /**< This operation has a memory input and may change the memory state. */
- irop_flag_dump_noblock = 0x00001000, /**< node should be dumped outside any blocks */
- irop_flag_dump_noinput = 0x00002000, /**< node is a placeholder for "no input" */
- irop_flag_machine = 0x00010000, /**< This operation is a machine operation. */
- irop_flag_machine_op = 0x00020000, /**< This operation is a machine operand. */
- irop_flag_cse_neutral = 0x00040000, /**< This operation is CSE neutral to its users. */
- irop_flag_user = 0x00080000 /**< This flag and all higher ones are free for machine user. */
+ irop_flag_none = 0, /**< Nothing. */
+ irop_flag_labeled = 1U << 0, /**< If set, output edge labels on in-edges in vcg graph. */
+ irop_flag_commutative = 1U << 1, /**< This operation is commutative. */
+ irop_flag_cfopcode = 1U << 2, /**< This operation is a control flow operation. */
+ irop_flag_fragile = 1U << 3, /**< Set if the operation can change the control flow because
+ of an exception. */
+ irop_flag_forking = 1U << 4, /**< Forking control flow at this operation. */
+ irop_flag_highlevel = 1U << 5, /**< This operation is a pure high-level one and can be
+ skipped in low-level optimizations. */
+ irop_flag_constlike = 1U << 6, /**< This operation has no arguments and is some
+ kind of a constant. */
+ irop_flag_always_opt = 1U << 7, /**< This operation must always be optimized .*/
+ irop_flag_keep = 1U << 8, /**< This operation can be kept in End's keep-alive list. */
+ irop_flag_start_block = 1U << 9, /**< This operation is always placed in the Start block. */
+ irop_flag_uses_memory = 1U << 10, /**< This operation has a memory input and may change the memory state. */
+ irop_flag_dump_noblock = 1U << 11, /**< node should be dumped outside any blocks */
+ irop_flag_dump_noinput = 1U << 12, /**< node is a placeholder for "no input" */
+ irop_flag_machine = 1U << 13, /**< This operation is a machine operation. */
+ irop_flag_machine_op = 1U << 14, /**< This operation is a machine operand. */
+ irop_flag_cse_neutral = 1U << 15, /**< This operation is CSE neutral to its users. */
+ irop_flag_user = 1U << 16, /**< This flag and all higher ones are free for machine user. */
} irop_flags;
/** The opcodes of the libFirm predefined operations. */
iro_Phi,
iro_Load, iro_Store, iro_Alloc, iro_Free, iro_Sync,
iro_Proj, iro_Tuple, iro_Id, iro_Bad, iro_Confirm,
- iro_Unknown, iro_Filter, iro_Break, iro_CallBegin, iro_EndReg, iro_EndExcept,
+ iro_Unknown,
iro_NoMem, iro_Mux, iro_CopyB,
iro_InstOf, iro_Raise, iro_Bound,
iro_Pin,
FIRM_API ir_op *op_Block;
FIRM_API ir_op *op_Borrow;
FIRM_API ir_op *op_Bound;
-FIRM_API ir_op *op_Break;
FIRM_API ir_op *op_Builtin;
FIRM_API ir_op *op_Call;
-FIRM_API ir_op *op_CallBegin;
FIRM_API ir_op *op_Carry;
FIRM_API ir_op *op_Cast;
FIRM_API ir_op *op_Cmp;
FIRM_API ir_op *op_DivMod;
FIRM_API ir_op *op_Dummy;
FIRM_API ir_op *op_End;
-FIRM_API ir_op *op_EndExcept;
-FIRM_API ir_op *op_EndReg;
FIRM_API ir_op *op_Eor;
-FIRM_API ir_op *op_Filter;
FIRM_API ir_op *op_Free;
FIRM_API ir_op *op_Id;
FIRM_API ir_op *op_IJmp;
FIRM_API ir_op *get_op_Bound (void);
FIRM_API ir_op *get_op_Break (void);
FIRM_API ir_op *get_op_Builtin (void);
-FIRM_API ir_op *get_op_CallBegin (void);
FIRM_API ir_op *get_op_Call (void);
FIRM_API ir_op *get_op_Carry (void);
FIRM_API ir_op *get_op_Cast (void);
FIRM_API ir_op *get_op_DivMod (void);
FIRM_API ir_op *get_op_Div (void);
FIRM_API ir_op *get_op_Dummy (void);
-FIRM_API ir_op *get_op_EndExcept (void);
-FIRM_API ir_op *get_op_EndReg (void);
FIRM_API ir_op *get_op_End (void);
FIRM_API ir_op *get_op_Eor (void);
FIRM_API ir_op *get_op_Filter (void);
FIRM_API void assure_irg_outs(ir_graph *irg);
-#ifdef INTERPROCEDURAL_VIEW
-/** Computes the out edges in interprocedural view */
-FIRM_API void compute_ip_outs(void);
-/** Frees the out datastructures. Sets the flag in irg to "outs_none". */
-FIRM_API void free_ip_outs(void);
-#endif
-
FIRM_API void free_irg_outs(ir_graph *irg);
FIRM_API void free_irp_outs(void);
* program. It is not the base class of
* all classes in a class hierarchy (as, e.g., "object" in java).
* - A degenerated graph that contains constant expressions.
- * - interprocedural outs state.
- * - a flag indicating validity of the interprocedural representation.
* - the output file name
*/
#ifndef FIRM_IR_IRPROG_H
{
int i, n_irgs;
-#ifdef INTERPROCEDURAL_VIEW
- assert(! get_interprocedural_view()); /* Else walking will not reach the Call nodes. */
-#endif
-
/* initialize */
free_callgraph();
return !some_outof_loop && some_in_loop;
}
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Check whether there is a parallel edge in the ip control flow.
- * Only
- */
-static int is_ip_head(ir_graph *n, ir_graph *pred)
-{
- int is_be = 0;
-
- int iv_rem = get_interprocedural_view();
- set_interprocedural_view(1);
- {
- ir_node *sblock = get_irg_start_block(n);
- int i, arity = get_Block_n_cfgpreds(sblock);
-
- for (i = 0; i < arity; i++) {
- ir_node *pred_cfop = skip_Proj(get_Block_cfgpred(sblock, i));
- if (is_CallBegin(pred_cfop)) { /* could be Unknown */
- ir_graph *ip_pred = get_irn_irg(pred_cfop);
- if ((ip_pred == pred) && is_backedge(sblock, i)) {
- is_be = 1;
- }
- }
- }
- }
- set_interprocedural_view(iv_rem);
- return is_be;
-}
-#endif /* INTERPROCEDURAL_VIEW */
-
/**
* Returns index of the predecessor with the smallest dfn number
* greater-equal than limit.
return index;
}
-#ifndef INTERPROCEDURAL_VIEW
static ir_graph *find_tail(ir_graph *n)
{
ir_graph *m;
set_irg_callee_backedge(m, res_index);
return get_irg_callee(m, res_index);
}
-#else
-static ir_graph *find_tail(ir_graph *n)
-{
- ir_graph *m;
- int i, res_index = -2;
-
- ir_graph *res;
- ir_graph *in_and_out = NULL;
- ir_graph *only_in = NULL;
- ir_graph *ip_in_and_out = NULL;
- ir_graph *ip_only_in = NULL;
-
- for (i = tos-1; i >= 0; --i) {
- ir_graph *pred = (i < tos -1) ? stack[i+1] : n;
- m = stack[i];
-
- if (is_head(m, n)) {
- //printf(" found 1a! "); DDM;
- in_and_out = m;
- if (is_ip_head(pred, m)) {
- //printf(" found 1b! "); DDM;
- ip_in_and_out = m;
- }
- } else if (!ip_only_in && is_endless_head(m, n)) {
- only_in = m;
- //printf(" found 2a! "); DDM;
- if (is_ip_head(pred, m)) {
- //printf(" found 2b! "); DDM;
- ip_only_in = m;
- }
- } else if (is_ip_head(pred, m)) {
- //printf(" found 3! "); DDM; This happens for self recursions in the second
- //assert(0); scc iteration (the one to flip the loop.)
- }
-
- if (ip_in_and_out) break; /* That's what we really want. */
-
- if (m == n) break; /* Don't walk past n on the stack! */
- }
-
-
- if (!in_and_out && !only_in)
- /* There is no loop */
- return NULL;
-
-
- /* Is there a head in the callgraph without a head in the
- ip cf graph? */
- assert(in_and_out || only_in);
-
- m = (ip_in_and_out) ? ip_in_and_out : ip_only_in;
-
- if (!m)
- m = (in_and_out) ? in_and_out : only_in;
-
- res_index = smallest_dfn_pred(m, get_irg_dfn(m) + 1);
- if (res_index == -2) /* no smallest dfn pred found. */
- res_index = largest_dfn_pred(m);
-
- set_irg_callee_backedge(m, res_index);
- res = get_irg_callee(m, res_index);
- return res;
-}
-#endif /* INTERPROCEDURAL_VIEW */
/*-----------------------------------------------------------*
* The core algorithm. *
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Compute an estimate of field temperature, i.e., field access heuristic.
- * @author Goetz Lindenmaier
- * @date 21.7.2004
- * @version $Id$
- */
-#include "config.h"
-
-#ifdef INTERPROCEDURAL_VIEW
-
-#include <math.h>
-
-#include "field_temperature.h"
-
-#include "trouts.h"
-#include "execution_frequency.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irprog_t.h"
-#include "entity_t.h"
-#include "irgwalk.h"
-#include "error.h"
-
-#include "array.h"
-
-/* *************************************************************************** */
-/* initialize, global variables. */
-/* *************************************************************************** */
-
-/* *************************************************************************** */
-/* The heuristic */
-/* *************************************************************************** */
-
-int get_irn_loop_call_depth(ir_node *n)
-{
- ir_graph *irg = get_irn_irg(n);
- return get_irg_loop_depth(irg);
-}
-
-int get_irn_cfloop_depth(ir_node *n)
-{
- ir_loop *l = get_irn_loop(get_nodes_block(n));
- if (l)
- return get_loop_depth(l);
- else
- return 0;
-}
-
-int get_irn_recursion_depth(ir_node *n)
-{
- ir_graph *irg = get_irn_irg(n);
- return get_irg_recursion_depth(irg);
-}
-
-
-/** @@@ the second version of the heuristic. */
-int get_weighted_loop_depth(ir_node *n)
-{
- int loop_call_depth = get_irn_loop_call_depth(n);
- int loop_depth = get_irn_cfloop_depth(n);
- int recursion_depth = get_irn_recursion_depth(n);
-
- return loop_call_depth + loop_depth + recursion_depth;
-}
-
-
-/* *************************************************************************** */
-/* The 2. heuristic */
-/* *************************************************************************** */
-
-static int default_recursion_weight = 5;
-
-/* The final evaluation of a node. In this function we can
- adapt the heuristic. Combine execution frequency with
- recursion depth.
- @@@ the second version of the heuristic.
-
- Return 0 if the node is neither in a loop nor in a recursion. */
-double get_irn_final_cost(ir_node *n)
-{
- double cost_loop = get_irn_exec_freq(n);
- double cost_method = get_irg_method_execution_frequency(get_irn_irg(n));
- int rec_depth = get_irn_recursion_depth(n);
- double cost_rec = 0;
-
-#if 0
- if (get_irn_recursion_depth(n) == 0 &&
- get_irn_loop_depth(n) == 0 &&
- get_irg_method_loop_depth(get_irn_irg(n)) == 0)
- return 0;
-#else
- if (get_weighted_loop_depth(n) == 0) return 0;
-#endif
-
- if (rec_depth) cost_rec = pow(default_recursion_weight, rec_depth);
- return cost_loop*(cost_method + cost_rec);
-}
-
-double get_type_estimated_n_instances(ir_type *tp)
-{
- int i, n_allocs = get_type_n_allocs(tp);
- double n_instances = 0;
- for (i = 0; i < n_allocs; ++i) {
- ir_node *alloc = get_type_alloc(tp, i);
- n_instances += get_irn_final_cost(alloc);
- }
- return n_instances;
-}
-
-double get_type_estimated_mem_consumption_bytes(ir_type *tp)
-{
- (void) tp;
- assert(0);
- return 0.0;
-}
-
-int get_type_estimated_n_fields(ir_type *tp)
-{
- int s = 0;
- switch (get_type_tpop_code(tp)) {
-
- case tpo_primitive:
- case tpo_pointer:
- case tpo_enumeration:
- s = 1;
- break;
-
- case tpo_class:
- s = 1; /* dispatch pointer */
- /* fall through */
- case tpo_struct: {
- int i, n_mem = get_compound_n_members(tp);
- for (i = 0; i < n_mem; ++i) {
- ir_entity *mem = get_compound_member(tp, i);
- if (get_entity_allocation(mem) == allocation_automatic) {
- s += get_type_estimated_n_fields(get_entity_type(mem));
- }
- }
- } break;
-
- case tpo_array: {
- long n_elt = DEFAULT_N_ARRAY_ELEMENTS;
- assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
- if (is_Const(get_array_lower_bound(tp, 0)) &&
- is_Const(get_array_upper_bound(tp, 0))) {
- n_elt = get_array_upper_bound_int(tp, 0) - get_array_upper_bound_int(tp, 0);
- }
- s = n_elt;
- } break;
-
- default:
- panic("Unsupported type in get_type_estimated_n_fields %+F", tp);
- }
-
- return s;
-}
-
-int get_type_estimated_size_bytes(ir_type *tp)
-{
- int s = 0;
-
- switch (get_type_tpop_code(tp)) {
-
- case tpo_primitive:
- case tpo_pointer:
- case tpo_enumeration:
- s = get_mode_size_bytes(get_type_mode(tp));
- break;
-
- case tpo_class:
- s = get_mode_size_bytes(mode_P_data); /* dispatch pointer */
- /* fall through */
- case tpo_struct: {
- int i, n_mem = get_compound_n_members(tp);
- for (i = 0; i < n_mem; ++i) {
- ir_entity *mem = get_compound_member(tp, i);
- s += get_type_estimated_size_bytes(get_entity_type(mem));
-
- if (get_entity_allocation(mem) == allocation_automatic) {
- } /* allocation_automatic */
- }
- } break;
-
- case tpo_array: {
- int elt_s = get_type_estimated_size_bytes(get_array_element_type(tp));
- long n_elt = DEFAULT_N_ARRAY_ELEMENTS;
- assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
- if (is_Const(get_array_lower_bound(tp, 0)) &&
- is_Const(get_array_upper_bound(tp, 0))) {
- n_elt = get_array_upper_bound_int(tp, 0) - get_array_lower_bound_int(tp, 0);
- }
- s = n_elt * elt_s;
- break;
- }
-
- default: assert(0);
- }
-
- return s;
-}
-
-double get_type_estimated_n_casts(ir_type *tp)
-{
- int i, n_casts = get_type_n_casts(tp);
- double n_instances = 0;
- for (i = 0; i < n_casts; ++i) {
- ir_node *cast = get_type_cast(tp, i);
- n_instances += get_irn_final_cost(cast);
- }
- return n_instances;
-}
-
-double get_class_estimated_n_upcasts(ir_type *clss)
-{
- double n_instances = 0;
- int i, j, n_casts, n_pointertypes;
-
- n_casts = get_type_n_casts(clss);
- for (i = 0; i < n_casts; ++i) {
- ir_node *cast = get_type_cast(clss, i);
- if (get_irn_opcode(cast) != iro_Cast) continue; /* Could be optimized away. */
-
- if (is_Cast_upcast(cast))
- n_instances += get_irn_final_cost(cast);
- }
-
- n_pointertypes = get_type_n_pointertypes_to(clss);
- for (j = 0; j < n_pointertypes; ++j) {
- n_instances += get_class_estimated_n_upcasts(get_type_pointertype_to(clss, j));
- }
-
- return n_instances;
-}
-
-double get_class_estimated_n_downcasts(ir_type *clss)
-{
- double n_instances = 0;
- int i, j, n_casts, n_pointertypes;
-
- n_casts = get_type_n_casts(clss);
- for (i = 0; i < n_casts; ++i) {
- ir_node *cast = get_type_cast(clss, i);
- if (get_irn_opcode(cast) != iro_Cast) continue; /* Could be optimized away. */
-
- if (is_Cast_downcast(cast))
- n_instances += get_irn_final_cost(cast);
- }
-
- n_pointertypes = get_type_n_pointertypes_to(clss);
- for (j = 0; j < n_pointertypes; ++j) {
- n_instances += get_class_estimated_n_downcasts(get_type_pointertype_to(clss, j));
- }
-
- return n_instances;
-}
-
-
-double get_class_estimated_dispatch_writes(ir_type *clss)
-{
- return get_type_estimated_n_instances(clss);
-}
-
-/** Returns the number of reads of the dispatch pointer. */
-double get_class_estimated_dispatch_reads (ir_type *clss)
-{
- int i, n_mems = get_class_n_members(clss);
- double n_calls = 0;
- for (i = 0; i < n_mems; ++i) {
- ir_entity *mem = get_class_member(clss, i);
- n_calls += get_entity_estimated_n_dyncalls(mem);
- }
- return n_calls;
-}
-
-double get_class_estimated_n_dyncalls(ir_type *clss)
-{
- return get_class_estimated_dispatch_reads(clss) +
- get_class_estimated_dispatch_writes(clss);
-}
-
-double get_entity_estimated_n_loads(ir_entity *ent)
-{
- int i, n_acc = get_entity_n_accesses(ent);
- double n_loads = 0;
- for (i = 0; i < n_acc; ++i) {
- ir_node *acc = get_entity_access(ent, i);
- if (is_Load(acc)) {
- n_loads += get_irn_final_cost(acc);
- }
- }
- return n_loads;
-}
-
-double get_entity_estimated_n_stores(ir_entity *ent)
-{
- int i, n_acc = get_entity_n_accesses(ent);
- double n_stores = 0;
- for (i = 0; i < n_acc; ++i) {
- ir_node *acc = get_entity_access(ent, i);
- if (is_Store(acc))
- n_stores += get_irn_final_cost(acc);
- }
- return n_stores;
-}
-
-/* @@@ Should we evaluate the callee array? */
-double get_entity_estimated_n_calls(ir_entity *ent)
-{
- int i, n_acc = get_entity_n_accesses(ent);
- double n_calls = 0;
- for (i = 0; i < n_acc; ++i) {
- ir_node *acc = get_entity_access(ent, i);
- if (is_Call(acc))
- n_calls += get_irn_final_cost(acc);
- }
- return n_calls;
-}
-
-double get_entity_estimated_n_dyncalls(ir_entity *ent)
-{
- int i, n_acc = get_entity_n_accesses(ent);
- double n_calls = 0;
- for (i = 0; i < n_acc; ++i) {
- ir_node *acc = get_entity_access(ent, i);
-
- /* Call->Sel(ent) combination */
- if (is_Call(acc) && is_Sel(get_Call_ptr(acc))) {
- n_calls += get_irn_final_cost(acc);
-
- /* MemOp->Sel combination for static, overwritten entities */
- } else if (is_memop(acc) && is_Sel(get_memop_ptr(acc))) {
- ir_entity *ent = get_Sel_entity(get_memop_ptr(acc));
- if (is_Class_type(get_entity_owner(ent))) {
- /* We might call this for inner entities in compounds. */
- if (get_entity_n_overwrites(ent) > 0 ||
- get_entity_n_overwrittenby(ent) > 0) {
- n_calls += get_irn_final_cost(acc);
- }
- }
- }
-
- }
- return n_calls;
-}
-
-#endif
switch (get_irn_opcode(n)) {
case iro_Block:
if (!get_Block_matured(n)) return NULL;
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view() && n->attr.block.in_cg) {
- assert(n->attr.block.cg_backedge && "backedge array not allocated!");
- return n->attr.block.cg_backedge;
- }
-#endif
assert(n->attr.block.backedge && "backedge array not allocated!");
return n->attr.block.backedge;
case iro_Phi:
assert(n->attr.phi.u.backedge && "backedge array not allocated!");
return n->attr.phi.u.backedge;
- case iro_Filter:
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view()) {
- assert(n->attr.filter.backedge && "backedge array not allocated!");
- return n->attr.filter.backedge;
- }
-#endif
- break;
default:
break;
}
if (opc == iro_Phi)
n->attr.phi.u.backedge = arr;
else if (opc == iro_Block) {
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view())
- n->attr.block.cg_backedge = arr;
- else
-#endif
- n->attr.block.backedge = arr;
+ n->attr.block.backedge = arr;
}
- else if (opc == iro_Filter)
- n->attr.filter.backedge = arr;
}
assert(legal_backarray(n));
}
-#ifdef INTERPROCEDURAL_VIEW
-int is_inter_backedge(ir_node *n, int pos)
-{
- int res;
- int rem = get_interprocedural_view();
- set_interprocedural_view(0);
- res = is_backedge(n, pos);
- set_interprocedural_view(rem);
- return res;
-}
-
-int is_intra_backedge(ir_node *n, int pos)
-{
- int res;
- int rem = get_interprocedural_view();
- set_interprocedural_view(1);
- res = is_backedge(n, pos);
- set_interprocedural_view(rem);
- return res;
-}
-#endif
-
-
/* Returns non-zero if the predecessor pos is a backedge. */
int is_backedge(ir_node *n, int pos)
{
void set_backedge(ir_node *n, int pos)
{
unsigned *ba = get_backarray(n);
- assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
+ assert(ba && "can only set backedges at Phi, Block nodes.");
rbitset_set(ba, pos);
}
void set_not_backedge(ir_node *n, int pos)
{
unsigned *ba = get_backarray(n);
- assert(ba && "can only set backedges at Phi, Filter, Block nodes.");
+ assert(ba && "can only set backedges at Phi, Block nodes.");
rbitset_clear(ba, pos);
}
{
int i, arity;
unsigned *ba;
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
- set_interprocedural_view(0);
-#endif
ba = get_backarray(n);
if (ba) {
arity = get_irn_arity(n);
for (i = 0; i < arity; i++)
rbitset_clear(ba, i);
}
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(1);
- ba = get_backarray (n);
- if (ba) {
- arity = get_irn_arity(n);
- for (i = 0; i < arity; i++)
- rbitset_clear(ba, i);
- }
- set_interprocedural_view(rem);
-#endif
}
/* Allocate a new backedge array on the obstack for given size. */
finish_stack();
}
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Initializes the scc algorithm for the interprocedural case.
- */
-static inline void init_ip_scc(struct obstack *obst)
-{
- init_scc_common();
- cg_walk(init_node, NULL, obst);
-
-#if EXPERIMENTAL_CFLOOP_TREE
- cg_walk(link_to_reg_end, NULL, NULL);
-#endif
-}
-#endif
-
/**
* Condition for breaking the recursion: n is the block
* that gets the initial control flow from the Start node.
struct obstack temp;
int i;
-#ifdef INTERPROCEDURAL_VIEW
- assert(!get_interprocedural_view() &&
- "use construct_ip_cf_backedges()");
-#endif
max_loop_depth = 0;
current_ir_graph = irg;
if (state != loopinfo_cf_consistent)
construct_cf_backedges(irg);
}
-
-#ifdef INTERPROCEDURAL_VIEW
-int construct_ip_cf_backedges (void)
-{
- ir_graph *rem = current_ir_graph;
- int rem_ipv = get_interprocedural_view();
- struct obstack temp;
- int i;
-
- assert(get_irp_ip_view_state() == ip_view_valid);
- max_loop_depth = 0;
- outermost_ir_graph = get_irp_main_irg();
-
- obstack_init(&temp);
- init_ip_scc(&temp);
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /** We have to start the walk at the same nodes as cg_walk. **/
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
-
- cfscc(get_irg_end_block(current_ir_graph));
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) cfscc(sb);
- }
-
- /* Walk all endless cfloops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
-
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++) {
- ir_node *el = get_End_keepalive(e, j);
- if (is_Block(el)) cfscc(el);
- }
- }
- }
-
- set_irg_loop(outermost_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_ip_consistent);
- assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
-
- obstack_free(&temp, NULL);
- current_ir_graph = rem;
- set_interprocedural_view(rem_ipv);
- return max_loop_depth;
-}
-#endif
-
-#if 0
-/**
- * Clear the intra- and the interprocedural
- * backedge information pf a block.
- */
-static void reset_backedges(ir_node *block)
-{
- int rem;
-
- assert(is_Block(block));
-#ifdef INTERPROCEDURAL_VIEW
- rem = get_interprocedural_view();
- set_interprocedural_view(1);
- clear_backedges(block);
- set_interprocedural_view(0);
- clear_backedges(block);
- set_interprocedural_view(rem);
-#else
- (void) rem;
- clear_backedges(block);
-#endif
-}
-
-/**
- * Reset all backedges of the first block of
- * a loop as well as all loop info for all nodes of this loop.
- * Recurse into all nested loops.
- */
-static void loop_reset_backedges(ir_loop *l)
-{
- int i;
- reset_backedges(get_loop_node(l, 0));
- for (i = 0; i < get_loop_n_nodes(l); ++i)
- set_irn_loop(get_loop_node(l, i), NULL);
- for (i = 0; i < get_loop_n_sons(l); ++i) {
- loop_reset_backedges(get_loop_son(l, i));
- }
-}
-
-/* Removes all cfloop information.
- Resets all backedges */
-static void free_cfloop_information(ir_graph *irg)
-{
- ir_loop *loop = get_irg_loop(irg);
- if (loop != NULL) {
- loop_reset_backedges(loop);
- set_irg_loop(irg, NULL);
- }
- set_irg_loopinfo_state(irg, loopinfo_none);
- /* We cannot free the cfloop nodes, they are on the obstack. */
-}
-
-
-void free_all_cfloop_information(void)
-{
- int i;
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
- set_interprocedural_view(1); /* To visit all filter nodes */
-#endif
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- free_cfloop_information(get_irp_irg(i));
- }
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem);
-#endif
-}
-
-#endif
free_irg_outs(get_irp_irg(i));
}
-
-/*------------------------------------------------------------*
- * This computes the outedges for in interprocedural graph. *
- * There is one quirk: *
- * The number of the outedges for each node is saved in *
- * the first member of the ir_node** array. Maybe we should *
- * change this to make it more portable... *
- *------------------------------------------------------------*/
-
-
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Inits the number of outedges for each node
- * before counting.
- */
-static void init_count(ir_node * node, void *env)
-{
- (void) env;
- node->out = (ir_node **) 1; /* 1 for the array size */
-}
-
-
-/**
- * Adjusts the out edge count for its predecessors
- * and adds the current arity to the overall count,
- * which is saved in "env"
- */
-static void node_arity_count(ir_node * node, void * env)
-{
- int *anz = (int *) env, arity, n_outs, i, start;
- ir_node *succ;
-
- arity = get_irn_arity(node);
- start = (is_Block(node)) ? 0 : -1;
-
- n_outs = 1 + arity + (-start); // ((is_Block(node)) ? 0 : 1); // Why + 1??
- *anz += n_outs;
-
- for (i = start; i < arity; i++) {
- succ = get_irn_n(node, i);
- succ->out = (ir_node **)INT_TO_PTR(PTR_TO_INT(succ->out) + 1);
- }
-}
-
-/*
- * Inits all nodes for setting the outedges
- * Returns the overall count of edges
- */
-int count_ip_outs(void)
-{
- int res = 0;
-
- cg_walk(init_count, node_arity_count, &res);
-
- return(res);
-}
-
-static int dummy_count = 0, global_count; /* Only for debugging */
-
-/**
- * For each node: Sets the pointer to array
- * in which the outedges are written later.
- * The current array start is transported in env
- */
-static void set_array_pointer(ir_node *node, void *env)
-{
- int n_outs;
- ir_node ***free = (ir_node ***) env;
-
- /* Allocate my array */
- n_outs = PTR_TO_INT(node->out); /* We wrote the count here in count_ip_outs */
- dummy_count += n_outs;
- assert(dummy_count <= global_count && "More outedges than initially counted!");
- node -> out = *free;
- *free = &((*free)[n_outs]);
- /* We count the successors again, the space will be sufficient.
- We use this counter to remember the position for the next back
- edge. */
- node -> out[0] = (ir_node *) 0;
-}
-
-
-/**
- * Adds an outedge from the predecessor to the
- * current node.
- */
-static void set_out_pointer(ir_node * node, void *env)
-{
- int i, arity = get_irn_arity(node);
- ir_node *succ;
- int start = (!is_Block(node)) ? -1 : 0;
- (void) env;
-
- for (i = start; i < arity; ++i) {
- succ = get_irn_n(node, i);
- succ->out[get_irn_n_outs(succ)+1] = node;
- succ->out[0] = INT_TO_PTR(get_irn_n_outs(succ) + 1);
- }
-}
-
-
-/*
- * Sets the outedges for all nodes.
- */
-void set_ip_outs(void)
-{
- ir_node **outedge_array = get_irp_ip_outedges();
- cg_walk(set_array_pointer, set_out_pointer, (void *) &outedge_array);
-}
-
-
-
-/*
- * Counts the outedges, allocates memory to save the
- * outedges and fills this outedge array in interprocedural
- * view!
- */
-void compute_ip_outs(void)
-{
- int n_out_edges;
- ir_node **out_edges;
-
- assert(get_irp_ip_view_state() == ip_view_valid &&
- "Cannot construct outs for invalid ip view.");
-
- if (irp->outs_state != outs_none) {
- free_ip_outs();
- }
-
- global_count = n_out_edges = count_ip_outs();
- out_edges = XMALLOCNZ(ir_node*, n_out_edges);
- set_irp_ip_outedges(out_edges);
- set_ip_outs();
-}
-
-void free_ip_outs(void)
-{
- ir_node **out_edges = get_irp_ip_outedges();
- if (out_edges != NULL) {
- free(out_edges);
- set_irp_ip_outedges(NULL);
- }
- irp->outs_state = outs_none;
-}
-#endif
-
-
void free_irg_outs(ir_graph *irg)
{
/* current_ir_graph->outs_state = outs_none; */
finish_stack();
}
-#ifdef INTERPROCEDURAL_VIEW
-static inline void init_ip_scc(struct obstack *obst)
-{
- init_scc_common();
- cg_walk(init_node, NULL, obst);
-
-#if EXPERIMENTAL_LOOP_TREE
- cg_walk(link_to_reg_end, NULL, NULL);
-#endif
-}
-#endif
-
/**
* Check weather a given node represents the outer most Start
* block. In intra-procedural view this is the start block of the
return 0;
}
-static inline int is_ip_Filter(ir_node *n)
-{
-#ifdef INTERPROCEDURAL_VIEW
- return is_Filter(n) && get_interprocedural_view();
-#else
- (void) n;
- return 0;
-#endif
-}
-
/* When to walk from nodes to blocks. Only for Control flow operations? */
static inline int get_start_index(ir_node *n)
{
(single) test showed the loop tree is deeper. */
if (get_irn_op(n) == op_Phi ||
is_Block(n) ||
- (is_ip_Filter(n)) || (
- get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
- get_irn_pinned(n) == op_pin_state_floats
- ))
+ (get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
+ get_irn_pinned(n) == op_pin_state_floats))
// Here we could test for backedge at -1 which is illegal
return 0;
else
{
ir_op *op = get_irn_op(n);
return ((op == op_Block) ||
- (op == op_Phi) ||
- (is_ip_Filter(n)));
+ (op == op_Phi));
}
/**
}
}
-#ifdef INTERPROCEDURAL_VIEW
-static void my_scc(ir_node *n)
-{
- int i;
- if (irn_visited_else_mark(n))
- return;
-
- /* Initialize the node */
- set_irn_dfn(n, current_dfn); /* Depth first number for this node */
- set_irn_uplink(n, current_dfn); /* ... is default uplink. */
- set_irn_loop(n, NULL);
- current_dfn ++;
- push(n);
-
- /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
- array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
- so is_backedge does not access array[-1] but correctly returns false! */
-
- if (!is_outermost_Start(n)) {
- int arity = get_irn_arity(n);
-
- for (i = get_start_index(n); i < arity; i++) {
- ir_node *m;
- if (is_backedge(n, i)) continue;
- m = get_irn_n(n, i); /* get_irn_ip_pred(n, i); */
- /* if (!m || is_Unknown(m)) continue; */
- my_scc(m);
- if (irn_is_in_stack(m)) {
- /* Uplink of m is smaller if n->m is a backedge.
- Propagate the uplink to mark the loop. */
- if (get_irn_uplink(m) < get_irn_uplink(n))
- set_irn_uplink(n, get_irn_uplink(m));
- }
- }
- }
-
- if (get_irn_dfn(n) == get_irn_uplink(n)) {
- /* This condition holds for
- 1) the node with the incoming backedge.
- That is: We found a loop!
- 2) Straight line code, because no uplink has been propagated, so the
- uplink still is the same as the dfn.
-
- But n might not be a proper loop head for the analysis. Proper loop
- heads are Block and Phi nodes. find_tail searches the stack for
- Block's and Phi's and takes those nodes as loop heads for the current
- loop instead and marks the incoming edge as backedge. */
-
- ir_node *tail = find_tail(n);
- if (tail) {
- /* We have a loop, that is no straight line code,
- because we found a loop head!
- Next actions: Open a new loop on the loop tree and
- try to find inner loops */
-
-#if NO_LOOPS_WITHOUT_HEAD
- /* This is an adaption of the algorithm from fiasco / optscc to
- * avoid loops without Block or Phi as first node. This should
- * severely reduce the number of evaluations of nodes to detect
- * a fixpoint in the heap analysis.
- * Further it avoids loops without firm nodes that cause errors
- * in the heap analyses. */
-
- ir_loop *l;
- int close;
- if ((get_loop_n_elements(current_loop) > 0) || (is_outermost_loop(current_loop))) {
- l = new_loop();
- close = 1;
- } else {
- l = current_loop;
- close = 0;
- }
-#else
- ir_loop *l = new_loop();
-#endif
-
- /* Remove the loop from the stack ... */
- pop_scc_unmark_visit(n);
-
- /* The current backedge has been marked, that is temporarily eliminated,
- by find tail. Start the scc algorithm
- anew on the subgraph that is left (the current loop without the backedge)
- in order to find more inner loops. */
- my_scc(tail);
-
- assert(irn_visited(n));
-#if NO_LOOPS_WITHOUT_HEAD
- if (close)
-#endif
- close_loop(l);
- } else {
- /* No loop head was found, that is we have straightline code.
- Pop all nodes from the stack to the current loop. */
- pop_scc_to_loop(n);
- }
- }
-}
-#endif /* INTERPROCEDURAL_VIEW */
-
/* Constructs backedge information for irg. In interprocedural view constructs
backedges for all methods called by irg, too. */
int construct_backedges(ir_graph *irg)
ir_loop *head_rem;
struct obstack temp;
-#ifdef INTERPROCEDURAL_VIEW
- assert(!get_interprocedural_view() &&
- "not implemented, use construct_ip_backedges()");
-#endif
-
max_loop_depth = 0;
current_ir_graph = irg;
outermost_ir_graph = irg;
return max_loop_depth;
}
-
-#ifdef INTERPROCEDURAL_VIEW
-int construct_ip_backedges(void)
-{
- ir_graph *rem = current_ir_graph;
- int rem_ipv = get_interprocedural_view();
- int i;
- strcut obstack temp;
-
- max_loop_depth = 0;
- assert(get_irp_ip_view_state() == ip_view_valid);
-
- outermost_ir_graph = get_irp_main_irg();
-
- obstack_init(&temp);
- init_ip_scc(&temp);
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /** We have to start the walk at the same nodes as cg_walk. **/
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb))
- continue;
-
- scc(get_irg_end(current_ir_graph));
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) scc(sb);
- }
-
- /* Walk all endless loops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
-
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++)
- scc(get_End_keepalive(e, j));
- }
- }
-
- set_irg_loop(outermost_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
- assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
-
- obstack_free(&temp, NULL);
- current_ir_graph = rem;
- set_interprocedural_view(rem_ipv);
- return max_loop_depth;
-}
-
-void my_construct_ip_backedges(void)
-{
- ir_graph *rem = current_ir_graph;
- int rem_ipv = get_interprocedural_view();
- int i;
-
- assert(get_irp_ip_view_state() == ip_view_valid);
-
- outermost_ir_graph = get_irp_main_irg();
-
- init_ip_scc();
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /** We have to start the walk at the same nodes as cg_walk. **/
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
-
- my_scc(get_irg_end(current_ir_graph));
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph))
- scc(sb);
- }
-
- /* Walk all endless loops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
-
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++) scc(get_End_keepalive(e, j));
- }
- }
-
- set_irg_loop(outermost_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
- assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
-
- current_ir_graph = rem;
- set_interprocedural_view(rem_ipv);
-}
-#endif
-
static void reset_backedges(ir_node *n)
{
if (is_possible_loop_head(n)) {
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
-
- set_interprocedural_view(1);
- clear_backedges(n);
- set_interprocedural_view(1);
clear_backedges(n);
- set_interprocedural_view(rem);
-#else
- clear_backedges(n);
-#endif
}
}
-
/*
static void loop_reset_backedges(ir_loop *l)
{
reset_backedges(n);
}
-
/** Removes all loop information.
Resets all backedges */
void free_loop_information(ir_graph *irg)
/* We cannot free the loop nodes, they are on the obstack. */
}
-
void free_all_loop_information(void)
{
int i;
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
- set_interprocedural_view(1); /* To visit all filter nodes */
-#endif
for (i = 0; i < get_irp_n_irgs(); i++) {
free_loop_information(get_irp_irg(i));
}
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem);
-#endif
}
/* ------------------------------------------------------------------- */
case iro_Tuple:
case iro_Bad:
case iro_NoMem:
- case iro_Break:
- case iro_CallBegin:
- case iro_EndReg:
- case iro_EndExcept:
break;
/* compute the type */
case iro_Const:
- tp = get_Const_type(n);
+ tp = get_Const_type(n);
break;
case iro_SymConst:
tp = get_SymConst_value_type(n);
case iro_Unknown:
tp = firm_unknown_type;
break;
- case iro_Filter:
- assert(0 && "Filter not implemented");
- break;
/* catch special cases with fallthrough to binop/unop cases in default. */
case iro_Sub:
int i;
int n_runs = 0;
bool rerun = true;
-#ifdef INTERPROCEDURAL_VIEW
- int old_ip_view = get_interprocedural_view();
-
- set_interprocedural_view(0); /* save this for later */
-#endif
/* init_tables has added main_irg to _live_graphs */
++n_runs;
}
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(old_ip_view); /* cover up our traces */
-#endif
-
return n_runs;
}
#define L irop_flag_labeled
#define C irop_flag_commutative
#define X irop_flag_cfopcode
-#define I irop_flag_ip_cfopcode
#define F irop_flag_fragile
#define Y irop_flag_forking
#define H irop_flag_highlevel
{
switch(get_irn_opcode(irn)) {
case iro_Jmp:
- case iro_Break:
- return 1;
case iro_Proj:
return 0;
default:
#define L irop_flag_labeled
#define C irop_flag_commutative
#define X irop_flag_cfopcode
-#define I irop_flag_ip_cfopcode
#define F irop_flag_fragile
#define Y irop_flag_forking
#define H irop_flag_highlevel
+++ /dev/null
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief Construction and removal of interprocedural representation
- * (explicit interprocedural dependencies).
- * @author Hubert Schmid
- * @date 09.06.2002
- * @version $Id$
- */
-#include "config.h"
-
-#ifdef INTERPROCEDURAL_VIEW
-
-#include <string.h>
-#include <stdbool.h>
-#include "ircgcons.h"
-
-#include "array.h"
-#include "irprog.h"
-#include "irnode_t.h"
-#include "irprog_t.h"
-#include "ircons_t.h"
-#include "irgmod.h"
-#include "irgwalk.h"
-#include "irflag_t.h"
-#include "irtools.h"
-
-/* Return the current state of the interprocedural view. */
-ip_view_state get_irp_ip_view_state(void)
-{
- return irp->ip_view;
-}
-
-/* Set the current state of the interprocedural view. */
-static void set_irp_ip_view(ip_view_state state)
-{
- irp->ip_view = state;
-}
-
-/* Set the state of the interprocedural view to invalid. */
-void set_irp_ip_view_invalid(void)
-{
- set_irp_ip_view(ip_view_invalid);
-}
-
-
-/* Data for each method */
-typedef struct {
- int count; /* Number of calleers. */
- bool open; /* Open method: called by an unknown caller */
- ir_node * reg, * mem, ** res; /* EndReg, Mem and Method return values */
- ir_node * except, * except_mem; /* EndExcept and Mem for exception return */
-} irg_data_t;
-
-static irg_data_t * irg_data_create(void)
-{
- return XMALLOCZ(irg_data_t);
-}
-
-/** Count the number of callers of each method and mark open methods.
- *
- * Fills the irg_data data structure.
- * Open methods are methods with an unknown caller, I.e., methods that
- * - are external visible
- * - are dereferenced somewhere within the program (i.e., the address of the
- * method is stored somewhere). */
-static void caller_init(int arr_length, ir_entity ** free_methods)
-{
- int i, j;
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- set_entity_link(get_irg_entity(get_irp_irg(i)), irg_data_create());
- }
- for (i = arr_length - 1; i >= 0; --i) {
- irg_data_t * data = get_entity_link(free_methods[i]);
- data->open = true;
- }
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- ir_graph * irg = get_irp_irg(i);
- ir_node * call;
- /* We collected all call nodes in a link list at the end node. */
- for (call = get_irn_link(get_irg_end(irg)); call; call = get_irn_link(call)) {
- if (!is_Call(call)) continue;
- for (j = get_Call_n_callees(call) - 1; j >= 0; --j) {
- ir_entity * ent = get_Call_callee(call, j);
- if (get_entity_irg(ent)) {
- irg_data_t * data = get_entity_link(ent);
-# ifndef CATE_jni
- assert(get_entity_irg(ent) && data);
- ++data->count;
-# endif /* ndef CATE_jni */
- } else {
- set_entity_link(ent, NULL);
- }
- }
- }
- }
-}
-
-/*
-static inline ir_node * tail(ir_node * node)
-{
- ir_node * link;
- for (; (link = get_irn_link(node)); node = link) ;
- return node;
-}
-*/
-
-/* Call-Operationen an die "link"-Liste von "call_tail" anhängen (und
- * "call_tail" aktualisieren), Proj-Operationen in die Liste ihrer Definition
- * (auch bei Proj->Call Operationen) und Phi-Operationen in die Liste ihres
- * Grundblocks einfügen. */
-static void collect_phicallproj_walker(ir_node * node, ir_node ** call_tail)
-{
- if (is_Call(node)) {
- /* Die Liste von Call an call_tail anhängen. */
- ir_node * link;
- assert(get_irn_link(*call_tail) == NULL);
- set_irn_link(*call_tail, node);
- /* call_tail aktualisieren: */
- for (link = get_irn_link(*call_tail); link; *call_tail = link, link = get_irn_link(link)) ;
- } else if (get_irn_op(node) == op_Proj) {
- ir_node * head = skip_Proj(get_Proj_pred(node));
- set_irn_link(node, get_irn_link(head));
- set_irn_link(head, node);
- /* call_tail gegebenenfalls aktualisieren: */
- if (head == *call_tail) {
- *call_tail = node;
- }
- } else if (get_irn_op(node) == op_Phi) {
- ir_node * block = get_nodes_block(node);
- set_irn_link(node, get_irn_link(block));
- set_irn_link(block, node);
- }
-}
-
-
-static void link(ir_node * head, ir_node * node)
-{
- if (node) {
- set_irn_link(node, get_irn_link(head));
- set_irn_link(head, node);
- }
-}
-
-
-/* Die Call-Operationen aller Graphen an den End-Operationen
- * verlinken, die Proj-Operationen an ihren Definitionen und die
- * Phi-Operationen an ihren Grundblöcken. Die Liste der Calls sieht
- * dann so aus: End -> Call -> Proj -> ... -> Proj -> Call -> Proj ->
- * ... -> Proj -> NULL. */
-static void collect_phicallproj(void)
-{
- int i;
-
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- ir_graph * irg = get_irp_irg(i);
- ir_node * start = get_irg_start(irg);
- ir_node * end = get_irg_end(irg);
- current_ir_graph = irg;
- assert(irg && start);
-
- set_using_irn_link(irg);
-
- /* Die speziellen Parameter der Start-Operation extra verlinken,
- * auch wenn sie nicht im intraprozeduralen Graphen erreichbar
- * sind. */
- link(start, get_irg_frame(irg));
- /* walk */
- irg_walk_graph(irg, firm_clear_link, (irg_walk_func *) collect_phicallproj_walker, &end);
-
- clear_using_irn_link(irg);
- }
-}
-
-
-/* Proj-Operation durch Filter-Operation im aktuellen Block ersetzen. */
-static ir_node * exchange_proj(ir_node * proj)
-{
- ir_node * filter;
- assert(get_irn_op(proj) == op_Proj);
- filter = new_Filter(get_Proj_pred(proj), get_irn_mode(proj), get_Proj_proj(proj));
- /* Die Proj- (Id-) Operation sollte im gleichen Grundblock stehen, wie die
- * Filter-Operation. */
- set_nodes_block(proj, get_nodes_block(filter));
- exchange(proj, filter);
- return filter;
-}
-
-
-/* Echt neue Block-Operation erzeugen. CSE abschalten! */
-static ir_node * create_Block(int n, ir_node ** in)
-{
- /* Turn off optimizations so that blocks are not merged again. */
- int rem_opt = get_opt_optimize();
- ir_node * block;
- set_optimize(0);
- block = new_Block(n, in);
- set_cur_block(block);
- set_optimize(rem_opt);
- return block;
-}
-
-
-static void prepare_irg_end(ir_graph * irg, irg_data_t * data);
-static void prepare_irg_end_except(ir_graph * irg, irg_data_t * data);
-
-
-/* If we use new_Unknown we get the Unknown of a graph. This can
- * cause cycles we don't want to see, as Unknwon is in the Start Block
- * of the procedure. Use unknown of outermost irg where the start
- * block has no predecessors. */
-static inline ir_node *get_cg_Unknown(ir_mode *m)
-{
- assert((get_Block_n_cfgpreds(get_irg_start_block(get_irp_main_irg())) == 1) &&
- (get_nodes_block(get_Block_cfgpred(get_irg_start_block(get_irp_main_irg()), 0)) ==
- get_irg_start_block(get_irp_main_irg())));
- return new_r_Unknown(get_irp_main_irg(), m);
-}
-
-
-/* IRG vorbereiten. Proj-Operationen der Start-Operation in Filter-Operationen
- * umwandeln. Die künstlichen Steuerzusammenflüsse EndReg und EndExcept
- * einfügen. An der Start-Operation hängt nach dem Aufruf eine Liste der
- * entsprechenden Filter-Knoten. */
-static void prepare_irg(ir_graph * irg, irg_data_t * data)
-{
- ir_node * start_block = get_irg_start_block(irg);
- ir_node * link, * proj;
- int n_callers = data->count + (data->open ? 1 : 0);
- ir_node ** in = NEW_ARR_F(ir_node *, n_callers);
-
- current_ir_graph = irg;
- set_irg_current_block(irg, start_block);
-
- /* Grundblock interprozedural machen. */
- /* "in" ist nicht initialisiert. Das passiert erst in "construct_start". */
- set_Block_cg_cfgpred_arr(start_block, n_callers, in);
- /* Proj-Operationen durch Filter-Operationen ersetzen und (sonst) in
- * den Start-Block verschieben. */
- for (proj = get_irn_link(get_irg_start(irg)); proj; proj = get_irn_link(proj)) {
- if (get_Proj_pred(proj) != get_irg_start(irg)
- || (get_Proj_proj(proj) != pn_Start_X_initial_exec && get_Proj_proj(proj) != pn_Start_T_args)) {
- ir_node * filter = exchange_proj(proj);
- set_Filter_cg_pred_arr(filter, n_callers, in);
- } else {
- set_nodes_block(proj, start_block);
- }
- }
-
- DEL_ARR_F(in);
-
- /* Liste der Filter-Operationen herstellen. Dabei muss man beachten,
- * dass oben für "verschiedene" Proj-Operationen wegen CSE nur eine
- * Filter-Operation erzeugt worden sein kann. */
- for (link = get_irg_start(irg), proj = get_irn_link(link); proj; proj = get_irn_link(proj)) {
- if (is_Id(proj)) { /* replaced with filter */
- ir_node * filter = get_Id_pred(proj);
- assert(is_Filter(filter));
- if (filter != link && get_irn_link(filter) == NULL) {
- set_irn_link(link, filter);
- link = filter;
- }
- }
- }
- /* Globle Einträge für ersetzte Operationen korrigieren. */
- set_irg_initial_exec(irg, skip_Id(get_irg_initial_exec(irg)));
- set_irg_frame (irg, skip_Id(get_irg_frame(irg)));
- set_irg_initial_mem (irg, skip_Id(get_irg_initial_mem(irg)));
-
- /* Unbekannten Aufrufer sofort eintragen. */
- if (data->open) {
- set_Block_cg_cfgpred(start_block, 0, get_cg_Unknown(mode_X));
- for (proj = get_irn_link(get_irg_start(irg)); proj; proj = get_irn_link(proj)) {
- if (is_Filter(proj)) {
- set_Filter_cg_pred(proj, 0, get_cg_Unknown(get_irn_mode(proj)));
- }
- }
- data->count = 1;
- } else {
- data->count = 0;
- }
-
- prepare_irg_end(irg, data);
- prepare_irg_end_except(irg, data);
-}
-
-
-/* Künstlicher Steuerzusammenfluss EndReg einfügen. */
-static void prepare_irg_end(ir_graph * irg, irg_data_t * data)
-{
- ir_node * end_block = get_irg_end_block(irg);
- ir_node * end = get_irg_end(irg);
- ir_node **ret_arr = NULL;
- ir_node **cfgpred_arr = get_Block_cfgpred_arr(end_block);
- int i, j;
- int n_ret = 0;
-
- for (i = get_Block_n_cfgpreds(end_block) - 1; i >= 0; --i) {
- if (is_Return(cfgpred_arr[i])) {
- if (ret_arr) {
- ARR_APP1(ir_node *, ret_arr, cfgpred_arr[i]);
- } else {
- ret_arr = NEW_ARR_F(ir_node *, 1);
- ret_arr[0] = cfgpred_arr[i];
- }
- ++n_ret;
- }
- }
-
- if (n_ret > 0) {
- int n_res = get_method_n_ress(get_entity_type(get_irg_entity(irg)));
- ir_node ** in = NEW_ARR_F(ir_node *, n_ret);
-
- /* block */
- for (i = n_ret - 1; i >= 0; --i) {
- set_irg_current_block(irg, get_nodes_block(ret_arr[i]));
- in[i] = new_Jmp();
- }
- create_Block(n_ret, in);
-
- /* end */
- data->reg = new_EndReg();
-
- /* mem */
- for (i = n_ret - 1; i >= 0; --i) {
- in[i] = get_Return_mem(ret_arr[i]);
- }
- data->mem = new_Phi(n_ret, in, mode_M);
- /* This Phi is a merge, therefore needs not be kept alive.
- It might be optimized away, though. */
- if (get_End_keepalive(end, get_End_n_keepalives(end)-1 ) == data->mem)
- set_End_keepalive(end, get_End_n_keepalives(end)-1, new_Bad());
-
- /* res */
- data->res = NEW_ARR_F(ir_node *, n_res);
- for (j = n_res - 1; j >= 0; --j) {
- ir_mode *mode = NULL;
- /* In[0] could be a Bad node with wrong mode. */
- for (i = n_ret - 1; i >= 0; --i) {
- in[i] = get_Return_res(ret_arr[i], j);
- if (!mode && get_irn_mode(in[i]) != mode_T)
- mode = get_irn_mode(in[i]);
- }
- if (mode)
- data->res[j] = new_Phi(n_ret, in, mode);
- else /* All preds are Bad */
- data->res[j] = new_Bad();
- }
-
- DEL_ARR_F(in);
- }
-
- if (ret_arr) DEL_ARR_F(ret_arr);
-}
-
-
-/* Künstlicher Steuerzusammenfluss EndExcept einfügen. */
-static void prepare_irg_end_except(ir_graph * irg, irg_data_t * data)
-{
- ir_node * end_block = get_irg_end_block(irg);
- ir_node * end = get_irg_end(irg);
- ir_node ** except_arr = NULL;
- int i;
- int n_except = 0;
- ir_node ** cfgpred_arr = get_Block_cfgpred_arr(end_block);
- for (i = get_Block_n_cfgpreds(end_block) - 1; i >= 0; --i) {
- if (! is_Return(cfgpred_arr[i])) {
- if (except_arr) {
- ARR_APP1(ir_node *, except_arr, cfgpred_arr[i]);
- } else {
- except_arr = NEW_ARR_F(ir_node *, 1);
- except_arr[0] = cfgpred_arr[i];
- }
- ++n_except;
- }
- }
- if (n_except > 0) {
- ir_node ** in = NEW_ARR_F(ir_node *, n_except);
- /* block */
- create_Block(n_except, except_arr);
- /* end_except */
- data->except = new_EndExcept();
- /* mem */
- for (i = n_except - 1; i >= 0; --i) {
- ir_node *node = skip_Proj(skip_Tuple(except_arr[i]));
- ir_op *op = get_irn_op(node);
- if (op == op_Call) {
- in[i] = new_r_Proj(irg, get_nodes_block(node), node, mode_M, pn_Call_M_except);
- } else if (op == op_Raise) {
- in[i] = new_r_Proj(irg, get_nodes_block(node), node, mode_M, pn_Raise_M);
- } else if (op == op_CopyB) {
- in[i] = new_r_Proj(irg, get_nodes_block(node), node, mode_M, pn_CopyB_M_except);
- } else {
- assert(is_fragile_op(node));
- /* We rely that all cfops have the memory output at the same position. */
- in[i] = new_r_Proj(irg, get_nodes_block(node), node, mode_M, 0);
- }
- }
- data->except_mem = new_Phi(n_except, in, mode_M);
- /* This Phi is a merge, therefor needs not be kept alive.
- It might be optimized away, though. */
- if (get_End_keepalive(end, get_End_n_keepalives(end)-1 )
- == data->except_mem)
- set_End_keepalive(end, get_End_n_keepalives(end)-1, new_Bad());
- DEL_ARR_F(in);
- }
- if (except_arr) DEL_ARR_F(except_arr);
-}
-
-
-/* Zwischengespeicherte Daten wieder freigeben. */
-static void cleanup_irg(ir_graph * irg)
-{
- ir_entity * ent = get_irg_entity(irg);
- irg_data_t * data = get_entity_link(ent);
- assert(data);
- if (data->res) DEL_ARR_F(data->res);
- set_entity_link(ent, NULL);
- free(data);
-}
-
-
-/* Alle Phi-Operationen aus "from_block" nach "to_block"
- * verschieben. Die Phi-Operationen müssen am zugehörigen Grundblock
- * verlinkt sein. Danach sind sie am neuen Grundblock verlinkt. */
-static void move_phis(ir_node * from_block, ir_node * to_block)
-{
- ir_node * phi;
- for (phi = get_irn_link(from_block); phi != NULL; phi = get_irn_link(phi)) {
- set_nodes_block(phi, to_block);
- }
- assert(get_irn_link(to_block) == NULL);
- set_irn_link(to_block, get_irn_link(from_block));
- set_irn_link(from_block, NULL);
-}
-
-
-/* Rekursiv die Operation "node" und alle ihre Vorgänger aus dem Block
- * "from_block" nach "to_block" verschieben.
- * Verschiebe ebenfalls die Projs aus diesen Operationen. */
-static void move_nodes(ir_node * from_block, ir_node * to_block, ir_node * node)
-{
- int i, arity = get_irn_arity(node);
- ir_node *proj;
-
- for (i = arity - 1; i >= 0; --i) {
- ir_node * pred = get_irn_n(node, i);
- if (get_nodes_block(pred) == from_block) {
- move_nodes(from_block, to_block, pred);
- }
- }
- set_nodes_block(node, to_block);
-
- /* Move projs of this node. */
- proj = get_irn_link(node);
- for (; proj; proj = skip_Id(get_irn_link(proj))) {
- if (get_irn_op(proj) != op_Proj && !is_Filter(proj)) continue;
- if ((get_nodes_block(proj) == from_block) && (skip_Proj(get_irn_n(proj, 0)) == node))
- set_nodes_block(proj, to_block);
- }
-}
-
-
-/* Abhängigkeiten vom Start-Block und den Filter-Operationen im
- * Start-Block auf den Aufrufer hinzufügen. */
-static void construct_start(ir_entity * caller, ir_entity * callee,
- ir_node * call, ir_node * exec)
-{
- irg_data_t *data = get_entity_link(callee);
- ir_graph *irg = get_entity_irg(callee);
- ir_node *start = get_irg_start(irg);
- ir_node *filter;
- (void) caller;
-
- assert(irg);
- assert(get_entity_peculiarity(callee) == peculiarity_existent); /* Else data is not initalized. */
- assert((0 <= data->count) &&
- (data->count < get_Block_cg_n_cfgpreds(get_nodes_block(start))));
-
- set_Block_cg_cfgpred(get_nodes_block(start), data->count, exec);
- for (filter = get_irn_link(start); filter; filter = get_irn_link(filter)) {
- if (!is_Filter(filter)) continue;
- if (get_Proj_pred(filter) == start) {
- switch ((int) get_Proj_proj(filter)) {
- case pn_Start_M:
- set_Filter_cg_pred(filter, data->count, get_Call_mem(call));
- break;
- case pn_Start_P_frame_base:
- /* "frame_base" wird nur durch Unknown dargestellt. Man kann ihn aber
- * auch explizit darstellen, wenn sich daraus Vorteile für die
- * Datenflussanalyse ergeben. */
- set_Filter_cg_pred(filter, data->count, get_cg_Unknown(get_irn_mode(filter)));
- break;
- case pn_Start_P_globals:
- /* "globals" wird nur durch Unknown dargestellt. Man kann ihn aber auch
- * explizit darstellen, wenn sich daraus Vorteile für die
- * Datenflussanalyse ergeben. */
- set_Filter_cg_pred(filter, data->count, get_cg_Unknown(get_irn_mode(filter)));
- break;
- default:
- /* not reached */
- assert(0 && "not reached");
- break;
- }
- } else {
- set_Filter_cg_pred(filter, data->count, get_Call_param(call, get_Proj_proj(filter)));
- }
- }
- ++data->count;
-}
-
-
-/* Abhängigkeiten für den Speicherzustand über alle aufgerufenen
- * Methoden bestimmen. */
-static void fill_mem(int length, irg_data_t * data[], ir_node * in[])
-{
- int i;
- for (i = 0; i < length; ++i) {
- if (data[i]) { /* explicit */
- if (data[i]->reg) {
- in[i] = data[i]->mem;
- } else {
- in[i] = new_Bad();
- }
- } else { /* unknown */
- in[i] = get_cg_Unknown(mode_M);
- }
- }
-}
-
-
-/* Abhängigkeiten für den Ausnahme-Speicherzustand über alle
- * aufgerufenen Methoden bestimmen. */
-static void fill_except_mem(int length, irg_data_t * data[], ir_node * in[])
-{
- int i;
- for (i = 0; i < length; ++i) {
- if (data[i]) { /* explicit */
- if (data[i]->except) {
- in[i] = data[i]->except_mem;
- } else {
- in[i] = new_Bad();
- }
- } else { /* unknown */
- in[i] = get_cg_Unknown(mode_M);
- }
- }
-}
-
-
-/* Abhängigkeiten für ein Ergebnis über alle aufgerufenen Methoden
- * bestimmen. */
-static void fill_result(int pos, int length, irg_data_t * data[], ir_node * in[], ir_mode *m)
-{
- int i;
- for (i = 0; i < length; ++i) {
- if (data[i]) { /* explicit */
- if (data[i]->reg) {
- in[i] = data[i]->res[pos];
- } else {
- in[i] = new_Bad();
- }
- } else { /* unknown */
- in[i] = get_cg_Unknown(m);
- }
- }
-}
-
-
-/* Proj auf Except-X einer Call-Operation (aus der Link-Liste) bestimmen. */
-static ir_node * get_except(ir_node * call)
-{
- /* Mit CSE könnte man das effizienter machen! Die Methode wird aber für jede
- * Aufrufstelle nur ein einziges Mal aufgerufen. */
- ir_node * proj;
- for (proj = get_irn_link(call); proj && get_irn_op(proj) == op_Proj; proj = get_irn_link(proj)) {
- if (get_Proj_proj(proj) == 1 && is_Call(get_Proj_pred(proj))) {
- return proj;
- }
- }
- return NULL;
-}
-
-/* Returns true if control flow operation exc is predecessor of end
- block in irg. Works also for Return nodes, not only exceptions. */
-static bool exc_branches_to_end(ir_graph *irg, ir_node *exc)
-{
- int i;
- ir_node *end = get_irg_end_block(irg);
- for (i = get_Block_n_cfgpreds(end) -1; i >= 0; --i)
- if (get_Block_cfgpred(end, i) == exc) return true;
- return false;
-}
-
-/* Returns true if only caller of irg is "Unknown". */
-static bool is_outermost_graph(ir_graph *irg)
-{
- irg_data_t * data = get_entity_link(get_irg_entity(irg));
- if (data->count) {
- return false;
- } else if (data->open) {
- /* Die Methode wird nur von "der" unbekannten Aufrufstelle
- * aufgerufen. Darstellung wird für diese Methode nicht
- * geändert. */
- } else {
- /* Methode kann nicht aufgerufen werden. Die Darstellung wird
- * für diese Methode nicht geändert. Das kann nicht vorkommen,
- * wenn zuvor "gc_irgs()" aufgerufen wurde. */
- }
- return true;
-}
-
-#ifdef INTERPROCEDURAL_VIEW
-/* Grundblock der Call-Operation aufteilen. CallBegin- und Filter-Operationen
- * einfügen. Die Steuer- und Datenflussabhängigkeiten von den aufgerufenen
- * Methoden auf die CallBegin-Operation, und von der Aufrufstelle auf die
- * aufgerufenen Methoden eintragen. */
-static void construct_call(ir_node * call)
-{
- int i, n_callees;
- ir_node *post_block, *pre_block, *except_block, * proj, *jmp, *call_begin;
- ir_node ** in;
- ir_entity * caller;
- ir_entity ** callees;
- ir_graph ** irgs;
- irg_data_t ** data;
-
- n_callees = get_Call_n_callees(call);
- post_block = get_nodes_block(call); /* block nach dem Aufruf */
- pre_block = create_Block(get_Block_n_cfgpreds(post_block),
- get_Block_cfgpred_arr(post_block)); /* block vor dem Aufruf (mit CallBegin) */
- except_block = NULL;
- jmp = new_Break(); /* Sprung für intraprozedurale Darstellung (in * pre_block) */
- call_begin = new_CallBegin(get_Call_ptr(call), call); /* (in pre_block) */
- /* CallBegin might be entry to endless recursion. */
- add_End_keepalive(get_irg_end(get_irn_irg(pre_block)), pre_block);
-
- in = NEW_ARR_F(ir_node *, n_callees);
- caller = get_irg_entity(current_ir_graph); /* entity des aktuellen ir_graph */
- callees = NEW_ARR_F(ir_entity *, n_callees); /* aufgerufene Methoden: entity */
- irgs = NEW_ARR_F(ir_graph *, n_callees); /* aufgerufene Methoden: ir_graph */
- data = NEW_ARR_F(irg_data_t *, n_callees); /* aufgerufene Methoden: irg_data_t */
-
- /* post_block kann bereits interprozedurale Steuerflussvorgänger
- * besitzen. Diese müssen dann auch noch für den pre_block gesetzt werden. */
- if (get_Block_cg_cfgpred_arr(post_block)) {
- set_Block_cg_cfgpred_arr(pre_block, get_Block_cg_n_cfgpreds(post_block),
- get_Block_cg_cfgpred_arr(post_block));
- remove_Block_cg_cfgpred_arr(post_block);
- }
-
- /* Operationen verschieben */
- move_phis(post_block, pre_block);
- move_nodes(post_block, pre_block, call);
- set_irn_in(post_block, 1, &jmp);
-
- /* Wiederverwendete Daten initialisieren. */
- for (i = 0; i < n_callees; ++i) {
- callees[i] = get_Call_callee(call, i);
- irgs[i] = get_entity_irg(callees[i]);
- data[i] = get_entity_link(callees[i]);
- /* Only entities that have an irg got a irg_data data structure.
- In others there is some arbitrary garbage in the link field. */
- if (!irgs[i]) { assert(!data[i]); data[i] = NULL; }
- }
-
- /*
- * Set flag to suppress verifying placement on proper irg:
- * optimization can return block on other irg.
- */
- set_interprocedural_view(1);
-
- /* Die interprozeduralen Steuerflussvorgänger des post_block
- * bestimmen. */
- for (i = 0; i < n_callees; ++i) {
- if (data[i]) { /* explicit */
- if (data[i]->reg) {
- in[i] = new_r_Proj(irgs[i], get_nodes_block(data[i]->reg),
- data[i]->reg, mode_X, data[i]->count);
- } else {
- in[i] = new_Bad();
- }
- } else { /* unknown */
- in[i] = get_cg_Unknown(mode_X);
- }
- }
- set_interprocedural_view(0);
-
- set_Block_cg_cfgpred_arr(post_block, n_callees, in);
-
- /* Die interprozeduralen Steuerflussvorgänger des except_block
- * bestimmen. */
- if ((proj = get_except(call)) != NULL) {
- int preds = 0;
- bool exc_to_end = false;
- if (exc_branches_to_end(current_ir_graph, proj)) {
- /* The Call aborts the procedure if it returns with an exception.
- If this is an outermost procedure, the normal handling of exceptions
- will generate a Break that goes to the end block. This is illegal
- Frim. So directly branch to the end block with all exceptions. */
- exc_to_end = true;
- if (is_outermost_graph(current_ir_graph)) {
- except_block = get_irg_end_block(current_ir_graph);
- } else {
- irg_data_t * tmp_data = get_entity_link(get_irg_entity(current_ir_graph));
- except_block = get_nodes_block(tmp_data->except);
- }
- } else {
- except_block = create_Block(1, &proj);
- set_nodes_block(proj, except_block);
- exchange(proj, new_Break());
- set_irg_current_block(current_ir_graph, pre_block);
- set_irn_n(except_block, 0, new_Proj(call, mode_X, pn_Call_X_except));
- set_irg_current_block(current_ir_graph, post_block);
- }
-
- /*
- * Set flag to suppress verifying placement on proper irg:
- * optimization can return block on other irg.
- */
- set_interprocedural_view(1);
-
- for (i = 0; i < n_callees; ++i) {
- ir_entity * callee = get_Call_callee(call, i);
- if (data[i]) { /* explicit */
- if (data[i]->except) {
- in[i] = new_r_Proj(get_entity_irg(callee), get_nodes_block(data[i]->except),
- data[i]->except, mode_X, data[i]->count);
- } else {
- in[i] = new_Bad();
- }
- } else { /* unknown */
- in[i] = get_cg_Unknown(mode_X);
- }
- }
-
- preds = n_callees;
- if (exc_to_end) {
- /* append all existing preds of the end block to new in array.
- * Normal access routine guarantees that with first visit we
- * get the normal preds, and from then on the _cg_ preds.
- * (interprocedural view is set!)
- * Do not add the exc pred of end we are replacing! */
- for (i = get_Block_n_cfgpreds(except_block)-1; i >= 0; --i) {
- ir_node *pred = get_Block_cfgpred(except_block, i);
- if (pred != proj) {
- ARR_APP1(ir_node *, in, pred);
- preds++;
- }
- }
- }
- set_Block_cg_cfgpred_arr(except_block, preds, in);
- }
- set_interprocedural_view(0);
-
- /* Diesen Vorgänger in den Start-Blöcken der aufgerufenen Methoden
- * eintragen. */
- set_irg_current_block(current_ir_graph, pre_block);
- for (i = 0; i < n_callees; ++i) {
- if (irgs[i]) /* Else there is not graph to call */
- construct_start(caller, callees[i], call, new_Proj(call_begin, mode_X, i));
- }
-
- /* Proj-Operationen in Filter-Operationen umwandeln und
- * interprozedurale Vorgänger einfügen. */
- set_irg_current_block(current_ir_graph, post_block);
- for (proj = get_irn_link(call); proj; proj = get_irn_link(proj)) {
- if (get_irn_op(proj) != op_Proj) continue;
- if (skip_Proj(get_Proj_pred(proj)) != call) continue;
- if (get_Proj_pred(proj) == call) {
- if (get_Proj_proj(proj) == pn_Call_M_regular) { /* memory */
- ir_node * filter;
-
- set_nodes_block(proj, post_block);
- filter = exchange_proj(proj);
- /* filter in die Liste der Phis aufnehmen */
- if (get_irn_link(filter) == NULL) { /* note CSE */
- set_irn_link(filter, get_irn_link(post_block));
- set_irn_link(post_block, filter);
- }
- fill_mem(n_callees, data, in);
- set_Filter_cg_pred_arr(filter, n_callees, in);
- } else if (get_Proj_proj(proj) == pn_Call_X_except) { /* except */
- /* nothing: siehe oben */
- } else if (get_Proj_proj(proj) == pn_Call_T_result) { /* results */
- /* nothing */
- } else if (get_Proj_proj(proj) == pn_Call_M_except) { /* except_mem */
- ir_node * filter;
-
- set_nodes_block(proj, post_block);
- assert(except_block);
- set_irg_current_block(current_ir_graph, except_block);
- filter = exchange_proj(proj);
- /* filter in die Liste der Phis aufnehmen */
- if (get_irn_link(filter) == NULL) { /* note CSE */
- set_irn_link(filter, get_irn_link(except_block));
- set_irn_link(except_block, filter);
- }
- set_irg_current_block(current_ir_graph, post_block);
- fill_except_mem(n_callees, data, in);
- set_Filter_cg_pred_arr(filter, n_callees, in);
- } else {
- assert(0 && "not reached");
- }
- } else { /* result */
- ir_node * filter;
-
- assert(is_Proj(get_Proj_pred(proj)) && get_Proj_pred(get_Proj_pred(proj)) == call);
- set_nodes_block(proj, post_block);
- filter = exchange_proj(proj);
- /* filter in die Liste der Phis aufnehmen */
- if (get_irn_link(filter) == NULL) { /* not CSE */
- set_irn_link(filter, get_irn_link(post_block));
- set_irn_link(post_block, filter);
- }
- fill_result(get_Proj_proj(filter), n_callees, data, in, get_irn_mode(filter));
- set_Filter_cg_pred_arr(filter, n_callees, in);
- }
- }
- DEL_ARR_F(in);
- DEL_ARR_F(callees);
- DEL_ARR_F(irgs);
- DEL_ARR_F(data);
-}
-#endif
-
-
-void cg_construct(int arr_len, ir_entity ** free_methods_arr)
-{
- int i;
-
- if (get_irp_ip_view_state() == ip_view_valid) return;
- if (get_irp_ip_view_state() == ip_view_invalid) cg_destruct();
- set_irp_ip_view(ip_view_valid);
-
- collect_phicallproj();
-
- /* count callers */
- caller_init(arr_len, free_methods_arr);
-
- /* prepare irgs */
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- ir_graph * irg = get_irp_irg(i);
- ir_entity * ent = get_irg_entity(irg);
- irg_data_t * data = get_entity_link(ent);
- if (data->count) {
- prepare_irg(irg, data);
- } else if (data->open) {
- /* Die Methode wird nur von "der" unbekannten Aufrufstelle
- * aufgerufen. Darstellung wird für diese Methode nicht
- * geändert. */
- } else {
- /* Methode kann nicht aufgerufen werden. Die Darstellung wird
- * für diese Methode nicht geändert. Das kann nicht vorkommen,
- * wenn zuvor "gc_irgs()" aufgerufen wurde. */
- }
- }
-
- /* construct calls */
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- ir_node * node;
-
- current_ir_graph = get_irp_irg(i);
- for (node = get_irn_link(get_irg_end(current_ir_graph)); node; node = get_irn_link(node)) {
- if (is_Call(node)) {
- int j, n_callees = get_Call_n_callees(node);
- for (j = 0; j < n_callees; ++j)
- if (get_entity_irg(get_Call_callee(node, j)))
- break;
- if (j < n_callees) /* There is an entity with a graph */
- construct_call(node);
- }
- }
- }
-
- /* cleanup irgs: Abschlussarbeiten: Die Vorgänger der Methoden noch
- * explizit setzen und die zwischengespeicherten Daten wieder
- * freigeben. */
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- cleanup_irg(get_irp_irg(i));
- }
-}
-
-
-
-static void destruct_walker(ir_node * node, void * env)
-{
- (void) env;
- if (is_Block(node)) {
- remove_Block_cg_cfgpred_arr(node);
- /* Do not turn Break into Jmp. Better: merge blocks right away.
- Well, but there are Breaks left.
- See exc1 from ajacs-rts/Exceptions.java. */
- if (get_Block_n_cfgpreds(node) == 1) {
- ir_node *pred = get_Block_cfgpred(node, 0);
- if (get_irn_op(pred) == op_Break)
- exchange(node, get_nodes_block(pred));
- }
- } else if (is_Filter(node)) {
- set_irg_current_block(current_ir_graph, get_nodes_block(node));
- exchange(node, new_Proj(get_Filter_pred(node), get_irn_mode(node), get_Filter_proj(node)));
- } else if (get_irn_op(node) == op_Break) {
- set_irg_current_block(current_ir_graph, get_nodes_block(node));
- exchange(node, new_Jmp());
- } else if (is_Call(node)) {
- remove_Call_callee_arr(node);
- } else if (get_irn_op(node) == op_Proj) {
- /* some ProjX end up in strange blocks. */
- set_nodes_block(node, get_nodes_block(get_Proj_pred(node)));
- }
-}
-
-
-void cg_destruct(void)
-{
- int i;
- if (get_irp_ip_view_state() != ip_view_no) {
- for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- ir_graph * irg = get_irp_irg(i);
- irg_walk_graph(irg, destruct_walker, firm_clear_link, NULL);
-
- set_irg_initial_exec(irg, skip_Id(get_irg_initial_exec(irg)));
- set_irg_frame (irg, skip_Id(get_irg_frame(irg)));
- set_irg_initial_mem (irg, skip_Id(get_irg_initial_mem(irg)));
- set_irg_end_reg (irg, get_irg_end(irg));
- set_irg_end_except (irg, get_irg_end(irg));
-
- set_irg_callee_info_state(irg, irg_callee_info_none);
- }
-
- set_irp_ip_view(ip_view_no);
- }
-}
-
-#endif
return res;
} /* new_bd_Sync */
-
-static ir_node *new_bd_EndReg(dbg_info *db, ir_node *block)
-{
- ir_node *res;
- ir_graph *irg = current_ir_graph;
-
- res = new_ir_node(db, irg, block, op_EndReg, mode_T, -1, NULL);
- set_irg_end_reg(irg, res);
- IRN_VRFY_IRG(res, irg);
- return res;
-} /* new_bd_EndReg */
-
-static ir_node *new_bd_EndExcept(dbg_info *db, ir_node *block)
-{
- ir_node *res;
- ir_graph *irg = current_ir_graph;
-
- res = new_ir_node(db, irg, block, op_EndExcept, mode_T, -1, NULL);
- set_irg_end_except(irg, res);
- IRN_VRFY_IRG (res, irg);
- return res;
-} /* new_bd_EndExcept */
-
static ir_node *new_bd_ASM(dbg_info *db, ir_node *block, int arity,
ir_node *in[], ir_asm_constraint *inputs, int n_outs,
ir_asm_constraint *outputs, int n_clobber,
return res;
} /* new_rd_Sync */
-ir_node *new_rd_EndReg(dbg_info *db, ir_graph *irg, ir_node *block)
-{
- ir_node *res;
-
- res = new_ir_node(db, irg, block, op_EndReg, mode_T, -1, NULL);
- set_irg_end_reg(irg, res);
- IRN_VRFY_IRG(res, irg);
- return res;
-} /* new_rd_EndReg */
-
-ir_node *new_rd_EndExcept(dbg_info *db, ir_graph *irg, ir_node *block)
-{
- ir_node *res;
-
- res = new_ir_node(db, irg, block, op_EndExcept, mode_T, -1, NULL);
- set_irg_end_except(irg, res);
- IRN_VRFY_IRG (res, irg);
- return res;
-} /* new_rd_EndExcept */
-
ir_node *new_rd_ASM(dbg_info *db, ir_node *block,
int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs,
{
return get_irg_bad(irg);
}
-ir_node *new_r_EndReg(ir_graph *irg, ir_node *block)
-{
- return new_rd_EndReg(NULL, irg, block);
-}
-ir_node *new_r_EndExcept(ir_graph *irg, ir_node *block)
-{
- return new_rd_EndExcept(NULL, irg, block);
-}
ir_node *new_r_NoMem(ir_graph *irg)
{
return get_irg_no_mem(irg);
return new_rd_Sync(db, current_ir_graph->current_block, arity, in);
} /* new_d_Sync */
-ir_node *new_d_EndReg(dbg_info *db)
-{
- return new_bd_EndReg(db, current_ir_graph->current_block);
-} /* new_d_EndReg */
-
-ir_node *new_d_EndExcept(dbg_info *db)
-{
- return new_bd_EndExcept(db, current_ir_graph->current_block);
-} /* new_d_EndExcept */
-
-
ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], ir_asm_constraint *inputs,
int n_outs, ir_asm_constraint *outputs, int n_clobber,
ident *clobber[], ident *text)
{
return get_irg_bad(current_ir_graph);
}
-ir_node *new_EndReg(void)
-{
- return new_d_EndReg(NULL);
-}
-ir_node *new_EndExcept(void)
-{
- return new_d_EndExcept(NULL);
-}
ir_node *new_NoMem(void)
{
return get_irg_no_mem(current_ir_graph);
static ir_node **construct_block_lists(ir_graph *irg)
{
int i;
-#ifdef INTERPROCEDURAL_VIEW
- int rem_view = get_interprocedural_view();
-#endif
int walk_flag = ir_resources_reserved(irg) & IR_RESOURCE_IRN_VISITED;
ir_graph *rem = current_ir_graph;
ird_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
-#ifdef INTERPROCEDURAL_VIEW
- /* Collect also EndReg and EndExcept. We do not want to change the walker. */
- set_interprocedural_view(0);
-#endif
-
- set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
- irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
- set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
- irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
-
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem_view);
-#endif
-
if (walk_flag) {
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
}
}
break;
-#ifdef INTERPROCEDURAL_VIEW
- case iro_Filter:
- if (!get_interprocedural_view())
- fprintf(F, "Proj'");
- else
- goto default_case;
- break;
-#endif
-
case iro_Proj: {
ir_node *pred = get_Proj_pred(n);
goto default_case;
} break;
-#ifdef INTERPROCEDURAL_VIEW
- case iro_Start:
- case iro_End:
- case iro_EndExcept:
- case iro_EndReg:
- if (get_interprocedural_view()) {
- fprintf(F, "%s %s", get_irn_opname(n), get_ent_dump_name(get_irg_entity(get_irn_irg(n))));
- break;
- } else
- goto default_case;
-#endif
-
- case iro_CallBegin: {
- ir_node *addr = get_CallBegin_ptr(n);
- ir_entity *ent = NULL;
- if (is_Sel(addr))
- ent = get_Sel_entity(addr);
- else if (is_Global(addr))
- ent = get_Global_entity(addr);
- fprintf(F, "%s", get_irn_opname(n));
- if (ent) fprintf(F, " %s", get_entity_name(ent));
- break;
- }
case iro_Load:
if (get_Load_align(n) == align_non_aligned)
fprintf(F, "ua");
case iro_Proj:
pred = get_Proj_pred(n);
proj_nr = get_Proj_proj(n);
-#ifdef INTERPROCEDURAL_VIEW
-handle_lut:
-#endif
code = get_irn_opcode(pred);
if (code == iro_Cmp)
}
}
break;
- case iro_Filter:
- proj_nr = get_Filter_proj(n);
-#ifdef INTERPROCEDURAL_VIEW
- if (! get_interprocedural_view()) {
- /* it's a Proj' */
- pred = get_Filter_pred(n);
- goto handle_lut;
- } else
-#endif
- fprintf(F, "%ld ", proj_nr);
- break;
case iro_Sel:
fprintf(F, "%s ", get_ent_dump_name(get_Sel_entity(n)));
break;
{
(void) F;
(void) n;
-#ifdef INTERPROCEDURAL_VIEW
- fprintf(F, " %lf*(%2.0lf + %2.0lf) = %2.0lf ",
- get_irn_exec_freq(n),
- get_irg_method_execution_frequency(get_irn_irg(n)),
- pow(5, get_irg_recursion_depth(get_irn_irg(n))),
- get_irn_exec_freq(n) * (get_irg_method_execution_frequency(get_irn_irg(n)) + pow(5, get_irg_recursion_depth(get_irn_irg(n))))
- );
-#endif
return;
}
switch (get_irn_opcode(n)) {
case iro_Start:
- case iro_EndReg:
- case iro_EndExcept:
case iro_End:
print_vcg_color(F, ird_color_anchor);
break;
ir_node *pred = get_irn_n(n, i);
assert(pred);
-#ifdef INTERPROCEDURAL_VIEW
- if ((get_interprocedural_view() && get_irn_visited(pred) < get_irn_visited(n)))
- continue; /* pred not dumped */
-#endif
-
if ((flags & ir_dump_flag_back_edges) && is_backedge(n, i)) {
fprintf(F, "backedge: {sourcename: \"");
} else {
void dump_cfg(FILE *F, ir_graph *irg)
{
-#ifdef INTERPROCEDURAL_VIEW
- int ipv = get_interprocedural_view();
-#endif
-
dump_vcg_header(F, get_irg_dump_name(irg), NULL, NULL);
-#ifdef INTERPROCEDURAL_VIEW
- if (ipv) {
- printf("Warning: dumping cfg not in interprocedural view!\n");
- set_interprocedural_view(0);
- }
-#endif
-
/* walk over the blocks in the graph */
irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, F);
dump_node(F, get_irg_bad(irg));
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(ipv);
-#endif
dump_vcg_footer(F);
}
return verbosity;
}
-static inline bool is_ip_Filter(ir_node *n)
-{
-#ifdef INTERPROCEDURAL_VIEW
- return is_Filter(n) && get_interprocedural_view();
-#else
- (void) n;
- return 0;
-#endif
-}
-
/* Write the irnode and all its attributes to the file passed. */
void dump_irnode_to_file(FILE *F, ir_node *n)
{
fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, -1)));
}
-#ifdef INTERPROCEDURAL_VIEW
- fprintf(F, " arity: %d\n", get_irn_intra_arity(n));
- /* show all predecessor nodes */
- fprintf(F, " pred nodes:\n");
- if (!is_Block(n)) {
- fprintf(F, " -1: ");
- dump_node_opcode(F, get_irn_n(n, -1));
- fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, -1)));
- }
- for ( i = 0; i < get_irn_intra_arity(n); ++i) {
- fprintf(F, " %d: %s ", i, is_intra_backedge(n, i) ? "be" : " ");
- dump_node_opcode(F, get_irn_intra_n(n, i));
- fprintf(F, " %ld\n", get_irn_node_nr(get_irn_intra_n(n, i)));
- }
-#else
fprintf(F, " arity: %d\n", get_irn_arity(n));
/* show all predecessor nodes */
fprintf(F, " pred nodes:\n");
dump_node_opcode(F, get_irn_n(n, i));
fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
}
-#endif
fprintf(F, " Private Attributes:\n");
if (is_Proj(n))
fprintf(F, " proj nr: %ld\n", get_Proj_proj(n));
-#ifdef INTERPROCEDURAL_VIEW
- if ((get_irp_ip_view_state() != ip_view_no) && (is_Filter(n) || is_Block(n))) {
- fprintf(F, " inter arity: %d\n", get_irn_inter_arity(n));
- fprintf(F, " inter pred nodes:\n");
- for (i = 0; i < get_irn_inter_arity(n); ++i) {
- fprintf(F, " %d: %s ", i, is_intra_backedge(n, i) ? "be" : " ");
- dump_node_opcode(F, get_irn_inter_n(n, i));
- fprintf(F, " %ld\n", get_irn_node_nr(get_irn_inter_n(n, i)));
- }
- }
-#endif
-
if (is_fragile_op(n)) {
fprintf(F, " pinned state: %s\n", get_op_pin_state_name(get_irn_pinned(n)));
/* not dumped: frag array */
/* This is not nice, output it as a marker in the predecessor list. */
if (is_Block(n) ||
- get_irn_op(n) == op_Phi ||
- (is_ip_Filter(n))) {
+ get_irn_op(n) == op_Phi) {
fprintf(F, " backedges:");
comma = ' ';
for (i = 0; i < get_irn_arity(n); i++)
fprintf(F, " Execution frequency statistics:\n");
if (get_irg_exec_freq_state(get_irn_irg(n)) != exec_freq_none)
fprintf(F, " procedure local evaluation: %8.2lf\n", get_irn_exec_freq(n));
-#ifdef INTERPROCEDURAL_VIEW
- if (get_irp_loop_nesting_depth_state() != loop_nesting_depth_none)
- fprintf(F, " call frequency of procedure: %8.2lf\n",
- get_irg_method_execution_frequency(get_irn_irg(n)));
- if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent)
- fprintf(F, " recursion depth of procedure: %8.2lf\n", (double)get_irn_recursion_depth(n));
- if ((get_irg_exec_freq_state(get_irn_irg(n)) != exec_freq_none) &&
- (get_irp_loop_nesting_depth_state() != loop_nesting_depth_none) &&
- (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent))
- fprintf(F, " final evaluation: **%8.2lf**\n", get_irn_final_cost(n));
-#endif
/* not dumped: graph_arr */
/* not dumped: mature */
ir_fprintf(F, " start of method of type %+F\n", tp);
for (i = 0; i < get_method_n_params(tp); ++i)
ir_fprintf(F, " param %d type: %+F\n", i, get_method_param_type(tp, i));
-#ifdef INTERPROCEDURAL_VIEW
- if ((get_irp_ip_view_state() == ip_view_valid) && !get_interprocedural_view()) {
- ir_node *sbl = get_nodes_block(n);
- int i, n_cfgpreds = get_Block_cg_n_cfgpreds(sbl);
- fprintf(F, " graph has %d interprocedural predecessors:\n", n_cfgpreds);
- for (i = 0; i < n_cfgpreds; ++i) {
- ir_node *cfgpred = get_Block_cg_cfgpred(sbl, i);
- fprintf(F, " %d: Call %ld in graph %s\n", i,
- get_irn_node_nr(cfgpred),
- get_irg_dump_name(get_irn_irg(cfgpred)));
- }
- }
-#endif
} break;
case iro_Cond: {
fprintf(F, " default ProjNr: %ld\n", get_Cond_default_proj(n));
}
}
} break;
- case iro_CallBegin: {
- ir_node *call = get_CallBegin_call(n);
- fprintf(F, " Call: %ld\n", get_irn_node_nr(call));
- if (Call_has_callees(call)) {
- fprintf(F, " possible callees:\n");
- for (i = 0; i < get_Call_n_callees(call); i++) {
- fprintf(F, " %d: %s\n", i, get_ent_dump_name(get_Call_callee(call, i)));
- }
- }
- } break;
case iro_Cast: {
ir_fprintf(F, " cast to type: %+F\n", get_Cast_type(n));
} break;
case iro_Return: {
-#ifdef INTERPROCEDURAL_VIEW
- if (!get_interprocedural_view()) {
-#endif
- ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
- ir_fprintf(F, " return in method of type %+F\n", tp);
- for (i = 0; i < get_method_n_ress(tp); ++i) {
- ir_fprintf(F, " result %d type: %+F\n", i,
- get_method_res_type(tp, i));
- }
-#ifdef INTERPROCEDURAL_VIEW
+ ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
+ ir_fprintf(F, " return in method of type %+F\n", tp);
+ for (i = 0; i < get_method_n_ress(tp); ++i) {
+ ir_fprintf(F, " result %d type: %+F\n", i,
+ get_method_res_type(tp, i));
}
-#endif
} break;
case iro_Const: {
assert(get_Const_type(n) != firm_none_type);
if (is_Method_type(get_entity_type(ent))) {
if (get_entity_irg(ent)) /* can be null */ {
fprintf(F, "\n%s irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
-#ifdef INTERPROCEDURAL_VIEW
- if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent) {
- fprintf(F, "\n%s recursion depth %d", prefix, get_irg_recursion_depth(get_entity_irg(ent)));
- fprintf(F, "\n%s loop depth %d", prefix, get_irg_loop_depth(get_entity_irg(ent)));
- }
-#endif
} else {
fprintf(F, "\n%s irg = NULL", prefix);
}
dump_node_list(F, (firm_kind *)ent, prefix, (int(*)(firm_kind *))get_entity_n_references,
(ir_node *(*)(firm_kind *, int))get_entity_reference, "References");
}
-
- if (verbosity & dump_verbosity_accessStats) {
- if (get_trouts_state() != outs_none) {
-#ifdef INTERPROCEDURAL_VIEW
- if (is_Method_type(get_entity_type(ent))) {
- fprintf(F, "%s Estimated #Calls: %lf\n", prefix, get_entity_estimated_n_calls(ent));
- fprintf(F, "%s Estimated #dynCalls: %lf\n", prefix, get_entity_estimated_n_calls(ent));
- } else {
- fprintf(F, "%s Estimated #Loads: %lf\n", prefix, get_entity_estimated_n_loads(ent));
- fprintf(F, "%s Estimated #Stores: %lf\n", prefix, get_entity_estimated_n_stores(ent));
- }
-#endif
- }
- }
}
void dump_entity_to_file(FILE *out, ir_entity *ent)
dump_type_list(F, tp, " ", get_type_n_pointertypes_to, get_type_pointertype_to, "PointerTpsTo");
}
-
- if (verbosity & dump_verbosity_accessStats) {
-#ifdef INTERPROCEDURAL_VIEW
- if (get_trouts_state() != outs_none) {
- fprintf(F, " Estimated #Instances: %lf\n", get_type_estimated_n_instances(tp));
- if (is_Class_type(tp) && (get_irp_typeinfo_state() != ir_typeinfo_none)) {
- fprintf(F, " Estimated #dyn Calls: %lf\n", get_class_estimated_n_dyncalls(tp));
- fprintf(F, " Estimated #Upcasts: %lf (#CastOps: %d)\n", get_class_estimated_n_upcasts(tp), get_class_n_upcasts(tp));
- fprintf(F, " Estimated #Downcasts: %lf (#CastOps: %d)\n", get_class_estimated_n_downcasts(tp), get_class_n_downcasts(tp));
- assert(get_class_n_upcasts(tp) + get_class_n_downcasts(tp) == get_type_n_casts(tp));
- }
- }
-#endif
-
- }
-
fprintf(F, "\n\n");
}
#include "config.h"
#include <string.h>
-#ifdef HAVE_STDDEF_H
-# include <stddef.h>
-#endif
+#include <stddef.h>
#include "xmalloc.h"
#include "ircons_t.h"
current_ir_graph = graph;
}
-#ifdef INTERPROCEDURAL_VIEW
-int firm_interprocedural_view = 0;
-
-int (get_interprocedural_view)(void)
-{
- return _get_interprocedural_view();
-}
-
-void (set_interprocedural_view)(int state)
-{
- firm_interprocedural_view = state;
-
- /* set function vectors for faster access */
- if (state) {
- _get_irn_arity = _get_irn_inter_arity;
- _get_irn_n = _get_irn_inter_n;
- }
- else {
- _get_irn_arity = _get_irn_intra_arity;
- _get_irn_n = _get_irn_intra_n;
- }
-}
-#endif
-
/** contains the suffix for frame type names */
static ident *frame_type_suffix = NULL;
set_cur_block(get_irg_end_block(res));
end = new_End();
set_irg_end (res, end);
- set_irg_end_reg (res, end);
- set_irg_end_except(res, end);
start_block = new_immBlock();
set_cur_block(start_block);
set_cur_block(end_block);
end = new_End();
set_irg_end (res, end);
- set_irg_end_reg (res, end);
- set_irg_end_except(res, end);
mature_immBlock(end_block);
/* -- The start block -- */
/* -- The end block -- */
set_irg_end_block (res, get_new_node(get_irg_end_block(irg)));
set_irg_end (res, get_new_node(get_irg_end(irg)));
- set_irg_end_reg (res, get_new_node(get_irg_end_reg(irg)));
- set_irg_end_except(res, get_new_node(get_irg_end_except(irg)));
/* -- The start block -- */
set_irg_start_block(res, get_new_node(get_irg_start_block(irg)));
_set_irg_end(irg, node);
}
-ir_node *(get_irg_end_reg)(const ir_graph *irg)
-{
- return _get_irg_end_reg(irg);
-}
-
-void (set_irg_end_reg)(ir_graph *irg, ir_node *node)
-{
- _set_irg_end_reg(irg, node);
-}
-
-ir_node *(get_irg_end_except)(const ir_graph *irg)
-{
- return _get_irg_end_except(irg);
-}
-
-void (set_irg_end_except)(ir_graph *irg, ir_node *node)
-{
- assert(get_irn_op(node) == op_EndExcept || is_End(node));
- _set_irg_end_except(irg, node);
-}
-
ir_node *(get_irg_initial_exec)(const ir_graph *irg)
{
return _get_irg_initial_exec(irg);
/** Returns the start block of a graph. */
static inline ir_node *_get_irg_start_block(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_start_block);
+ return get_irn_n(irg->anchor, anchor_start_block);
}
static inline void _set_irg_start_block(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_start(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_start);
+ return get_irn_n(irg->anchor, anchor_start);
}
static inline void _set_irg_start(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_end_block(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_end_block);
+ return get_irn_n(irg->anchor, anchor_end_block);
}
static inline void _set_irg_end_block(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_end(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_end);
+ return get_irn_n(irg->anchor, anchor_end);
}
static inline void _set_irg_end(ir_graph *irg, ir_node *node)
set_irn_n(irg->anchor, anchor_end, node);
}
-static inline ir_node *_get_irg_end_reg(const ir_graph *irg)
-{
- return get_irn_intra_n(irg->anchor, anchor_end_reg);
-}
-
-static inline void _set_irg_end_reg(ir_graph *irg, ir_node *node)
-{
- set_irn_n(irg->anchor, anchor_end_reg, node);
-}
-
-static inline ir_node *_get_irg_end_except(const ir_graph *irg)
-{
- return get_irn_intra_n(irg->anchor, anchor_end_except);
-}
-
-static inline void _set_irg_end_except(ir_graph *irg, ir_node *node)
-{
- set_irn_n(irg->anchor, anchor_end_except, node);
-}
-
static inline ir_node *_get_irg_initial_exec(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_initial_exec);
+ return get_irn_n(irg->anchor, anchor_initial_exec);
}
static inline void _set_irg_initial_exec(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_frame(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_frame);
+ return get_irn_n(irg->anchor, anchor_frame);
}
static inline void _set_irg_frame(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_tls(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_tls);
+ return get_irn_n(irg->anchor, anchor_tls);
}
static inline void _set_irg_tls(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_initial_mem(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_initial_mem);
+ return get_irn_n(irg->anchor, anchor_initial_mem);
}
static inline void _set_irg_initial_mem(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_args(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_args);
+ return get_irn_n(irg->anchor, anchor_args);
}
static inline void _set_irg_args(ir_graph *irg, ir_node *node)
static inline ir_node *_get_irg_bad(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_bad);
+ return get_irn_n(irg->anchor, anchor_bad);
}
static inline void _set_irg_bad(ir_graph *irg, ir_node *node)
static inline ir_node * _get_irg_no_mem(const ir_graph *irg)
{
- return get_irn_intra_n(irg->anchor, anchor_no_mem);
+ return get_irn_n(irg->anchor, anchor_no_mem);
}
static inline void _set_irg_no_mem(ir_graph *irg, ir_node *node)
*/
static inline ir_node *get_irg_anchor(const ir_graph *irg, int idx)
{
- return get_irn_intra_n(irg->anchor, idx);
+ return get_irn_n(irg->anchor, idx);
}
/**
}
-#ifdef INTERPROCEDURAL_VIEW
-extern int firm_interprocedural_view;
-
-static inline int _get_interprocedural_view(void)
-{
- return firm_interprocedural_view;
-}
-
-#define get_interprocedural_view() _get_interprocedural_view()
-#endif
-
#define is_ir_graph(thing) _is_ir_graph(thing)
#define get_irg_start_block(irg) _get_irg_start_block(irg)
#define set_irg_start_block(irg, node) _set_irg_start_block(irg, node)
#define set_irg_end_block(irg, node) _set_irg_end_block(irg, node)
#define get_irg_end(irg) _get_irg_end(irg)
#define set_irg_end(irg, node) _set_irg_end(irg, node)
-#define get_irg_end_reg(irg) _get_irg_end_reg(irg)
-#define set_irg_end_reg(irg, node) _set_irg_end_reg(irg, node)
-#define get_irg_end_except(irg) _get_irg_end_except(irg)
-#define set_irg_end_except(irg, node) _set_irg_end_except(irg, node)
#define get_irg_initial_exec(irg) _get_irg_initial_exec(irg)
#define set_irg_initial_exec(irg, node) _set_irg_initial_exec(irg, node)
#define get_irg_frame(irg) _get_irg_frame(irg)
#include "irprog.h"
#include "irgwalk.h"
#include "irhooks.h"
-#include "ircgcons.h"
#include "entity_t.h"
#include "error.h"
#include "pset_new.h"
#include "array.h"
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Walk over an interprocedural graph (callgraph).
- * Visits only graphs in irg_set.
- */
-static void irg_walk_cg(ir_node * node, ir_visited_t visited,
- pset_new_t *irg_set, irg_walk_func *pre,
- irg_walk_func *post, void * env)
-{
- int i;
- ir_graph * rem = current_ir_graph;
- ir_node * pred;
-
- assert(node && node->kind == k_ir_node);
- if (get_irn_visited(node) >= visited) return;
-
- set_irn_visited(node, visited);
-
- if (pre) pre(node, env);
-
- pred = skip_Proj(node);
- if (is_CallBegin(pred) ||
- get_irn_op(pred) == op_EndReg ||
- get_irn_op(pred) == op_EndExcept) {
- current_ir_graph = get_irn_irg(pred);
- }
-
- if (is_no_Block(node)) { /* not block */
- irg_walk_cg(get_nodes_block(node), visited, irg_set, pre, post, env);
- }
-
- if (is_Block(node)) { /* block */
- for (i = get_irn_arity(node) - 1; i >= 0; --i) {
- ir_node * exec = get_irn_n(node, i);
- ir_node * pred = skip_Proj(exec);
- if ((
- !is_CallBegin(pred) &&
- get_irn_op(pred) != op_EndReg &&
- get_irn_op(pred) != op_EndExcept
- ) || pset_new_contains(irg_set, get_irn_irg(pred))) {
- irg_walk_cg(exec, visited, irg_set, pre, post, env);
- }
- }
- } else if (is_Filter(node)) { /* filter */
- for (i = get_irn_arity(node) - 1; i >= 0; --i) {
- ir_node * pred = get_irn_n(node, i);
- if (is_Unknown(pred) || is_Bad(pred)) {
- irg_walk_cg(pred, visited, irg_set, pre, post, env);
- } else {
- ir_node * exec;
- exec = skip_Proj(get_Block_cfgpred(get_nodes_block(node), i));
-
- if (is_Bad(exec)) {
- continue;
- }
-
- assert(is_CallBegin(exec) ||
- get_irn_op(exec) == op_EndReg ||
- get_irn_op(exec) == op_EndExcept);
- if (pset_new_contains(irg_set, get_irn_irg(exec))) {
- current_ir_graph = get_irn_irg(exec);
- irg_walk_cg(pred, visited, irg_set, pre, post, env);
- current_ir_graph = rem;
- }
- }
- }
- } else { /* everything else */
- for (i = get_irn_arity(node) - 1; i >= 0; --i) {
- irg_walk_cg(get_irn_n(node, i), visited, irg_set, pre, post, env);
- }
- }
-
- if (post) post(node, env);
-
- current_ir_graph = rem;
-}
-
-/**
- * Insert all ir_graphs in irg_set, that are (transitive) reachable.
- */
-static void collect_irgs(ir_node * node, pset_new_t *irg_set)
-{
- if (is_Call(node)) {
- int i;
- for (i = get_Call_n_callees(node) - 1; i >= 0; --i) {
- ir_entity * ent = get_Call_callee(node, i);
- ir_graph * irg = get_entity_irg(ent);
- if (irg && !pset_new_contains(irg_set, irg)) {
- pset_new_insert(irg_set, irg);
- irg_walk_graph(irg, (irg_walk_func *) collect_irgs, NULL, irg_set);
- }
- }
- }
-}
-#endif
-
/**
* specialized version of irg_walk_2, called if only pre callback exists
*
void *env)
{
assert(is_ir_node(node));
-
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view()) {
- pset_new_t irg_set;
- pset_new_iterator_t iter;
- ir_visited_t visited;
- ir_graph *irg;
- assert(get_irp_ip_view_state() == ip_view_valid);
-
- pset_new_init(&irg_set);
- set_interprocedural_view(0);
- pset_new_insert(&irg_set, current_ir_graph);
- irg_walk(node, (irg_walk_func *) collect_irgs, NULL, &irg_set);
- set_interprocedural_view(1);
- visited = get_max_irg_visited() + 1;
-
- foreach_pset_new(&irg_set, irg, iter) {
- set_irg_visited(irg, visited);
- }
- irg_walk_cg(node, visited, &irg_set, pre, post, env);
- pset_new_destroy(&irg_set);
- } else {
-#endif
- nodes_touched = irg_walk_2(node, pre, post, env);
-#ifdef INTERPROCEDURAL_VIEW
- }
-#endif
+ nodes_touched = irg_walk_2(node, pre, post, env);
}
void irg_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post,
{
assert(is_ir_node(node));
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view()) {
- panic("This is not yet implemented.");
- }
-#endif
ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
inc_irg_visited(current_ir_graph);
nodes_touched = irg_walk_in_or_dep_2(node, pre, post, env);
current_ir_graph = rem;
}
-/***************************************************************************/
-
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Returns current_ir_graph and sets it to the irg of predecessor index
- * of node n.
- */
-static inline ir_graph * switch_irg(ir_node *n, int index)
-{
- ir_graph *old_current = current_ir_graph;
-
- if (get_interprocedural_view()) {
- /* Only Filter and Block nodes can have predecessors in other graphs. */
- if (is_Filter(n))
- n = get_nodes_block(n);
- if (is_Block(n)) {
- ir_node *cfop = skip_Proj(get_Block_cfgpred(n, index));
- if (is_ip_cfop(cfop)) {
- current_ir_graph = get_irn_irg(cfop);
- }
- }
- }
-
- return old_current;
-}
-
-static void cg_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void * env)
-{
- int i;
- ir_graph *rem = NULL;
- assert(node);
-
- if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
- set_irn_visited(node, get_irg_visited(current_ir_graph));
-
- if (pre) pre(node, env);
-
- if (is_no_Block(node))
- cg_walk_2(get_nodes_block(node), pre, post, env);
- for (i = get_irn_arity(node) - 1; i >= 0; --i) {
- rem = switch_irg(node, i); /* @@@ AS: Is this wrong? We do have to
- switch to the irg of the predecessor, don't we? */
- cg_walk_2(get_irn_n(node, i), pre, post, env);
- current_ir_graph = rem;
- }
-
- if (post) post(node, env);
- }
-}
-
-/* Walks all irgs in interprocedural view. Visits each node only once. */
-void cg_walk(irg_walk_func *pre, irg_walk_func *post, void *env)
-{
- int i;
- ir_graph *rem = current_ir_graph;
- int rem_view = get_interprocedural_view();
-
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- /* Fix all irg_visited flags */
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
-
- cg_walk_2(get_irg_end(current_ir_graph), pre, post, env);
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) {
- cg_walk_2(sb, pre, post, env);
- }
- }
-
- /* Walk all endless loops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++)
- cg_walk_2(get_End_keepalive(e, j), pre, post, env);
- }
- }
-
- set_interprocedural_view(rem_view);
- current_ir_graph = rem;
-}
-#endif
-
-
/***************************************************************************/
/* Walks back from n until it finds a real cf op. */
hook_irg_block_walk(irg, node, (generic_func *)pre, (generic_func *)post);
assert(node);
-#ifdef INTERPROCEDURAL_VIEW
- assert(!get_interprocedural_view()); /* interprocedural_view not implemented, because it
- * interleaves with irg_walk */
-#endif
ir_reserve_resources(irg, IR_RESOURCE_BLOCK_VISITED);
inc_irg_block_visited(irg);
block = is_Block(node) ? node : get_nodes_block(node);
blk_collect_data_t blks;
block_entry_t *entry;
-#ifdef INTERPROCEDURAL_VIEW
- /* switch off interprocedural view */
- int old_view = get_interprocedural_view();
- set_interprocedural_view(0);
-#endif
-
obstack_init(&blks.obst);
blks.blk_map = new_pset(addr_cmp, 1);
blks.blk_list = NEW_ARR_F(ir_node *, 0);
del_pset(blks.blk_map);
obstack_free(&blks.obst, NULL);
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(old_view);
-#endif
ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
}
return _is_ir_node(thing);
}
-int (get_irn_intra_arity)(const ir_node *node)
-{
- return _get_irn_intra_arity(node);
-}
-
-int (get_irn_inter_arity)(const ir_node *node)
-{
- return _get_irn_inter_arity(node);
-}
-
-int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity;
-
int (get_irn_arity)(const ir_node *node)
{
return _get_irn_arity(node);
consecutive. */
ir_node **get_irn_in(const ir_node *node)
{
- assert(node);
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view()) { /* handle Filter and Block specially */
- if (get_irn_opcode(node) == iro_Filter) {
- assert(node->attr.filter.in_cg);
- return node->attr.filter.in_cg;
- } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
- return node->attr.block.in_cg;
- }
- /* else fall through */
- }
-#endif /* INTERPROCEDURAL_VIEW */
return node->in;
}
ir_node *** pOld_in;
ir_graph *irg = get_irn_irg(node);
- assert(node);
-#ifdef INTERPROCEDURAL_VIEW
- if (get_interprocedural_view()) { /* handle Filter and Block specially */
- ir_opcode code = get_irn_opcode(node);
- if (code == iro_Filter) {
- assert(node->attr.filter.in_cg);
- pOld_in = &node->attr.filter.in_cg;
- } else if (code == iro_Block && node->attr.block.in_cg) {
- pOld_in = &node->attr.block.in_cg;
- } else {
- pOld_in = &node->in;
- }
- } else
-#endif /* INTERPROCEDURAL_VIEW */
- pOld_in = &node->in;
+ pOld_in = &node->in;
for (i = 0; i < arity; i++) {
memcpy((*pOld_in) + 1, in, sizeof(ir_node *) * arity);
}
-ir_node *(get_irn_intra_n)(const ir_node *node, int n)
-{
- return _get_irn_intra_n(node, n);
-}
-
-ir_node *(get_irn_inter_n)(const ir_node *node, int n)
-{
- return _get_irn_inter_n(node, n);
-}
-
-ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
-
ir_node *(get_irn_n)(const ir_node *node, int n)
{
return _get_irn_n(node, n);
assert(n < get_irn_arity(node));
assert(in && in->kind == k_ir_node);
-#ifdef INTERPROCEDURAL_VIEW
- if ((n == -1) && (get_irn_opcode(node) == iro_Filter)) {
- /* Change block pred in both views! */
- node->in[n + 1] = in;
- assert(node->attr.filter.in_cg);
- node->attr.filter.in_cg[n + 1] = in;
- return;
- }
- if (get_interprocedural_view()) { /* handle Filter and Block specially */
- if (get_irn_opcode(node) == iro_Filter) {
- assert(node->attr.filter.in_cg);
- node->attr.filter.in_cg[n + 1] = in;
- return;
- } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
- node->attr.block.in_cg[n + 1] = in;
- return;
- }
- /* else fall through */
- }
-#endif /* INTERPROCEDURAL_VIEW */
-
/* Call the hook */
hook_set_irn_n(node, n, in, node->in[n + 1]);
return _Block_block_visited(node);
}
-#ifdef INTERPROCEDURAL_VIEW
-void set_Block_cg_cfgpred_arr(ir_node *node, int arity, ir_node *in[])
-{
- assert(is_Block(node));
- if (node->attr.block.in_cg == NULL || arity != ARR_LEN(node->attr.block.in_cg) - 1) {
- node->attr.block.in_cg = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1);
- node->attr.block.in_cg[0] = NULL;
- node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity);
- {
- /* Fix backedge array. fix_backedges() operates depending on
- interprocedural_view. */
- int ipv = get_interprocedural_view();
- set_interprocedural_view(1);
- fix_backedges(current_ir_graph->obst, node);
- set_interprocedural_view(ipv);
- }
- }
- memcpy(node->attr.block.in_cg + 1, in, sizeof(ir_node *) * arity);
-}
-
-void set_Block_cg_cfgpred(ir_node *node, int pos, ir_node *pred)
-{
- assert(is_Block(node) && node->attr.block.in_cg &&
- 0 <= pos && pos < ARR_LEN(node->attr.block.in_cg) - 1);
- node->attr.block.in_cg[pos + 1] = pred;
-}
-
-ir_node **get_Block_cg_cfgpred_arr(ir_node *node)
-{
- assert(is_Block(node));
- return node->attr.block.in_cg == NULL ? NULL : node->attr.block.in_cg + 1;
-}
-
-int get_Block_cg_n_cfgpreds(const ir_node *node)
-{
- assert(is_Block(node));
- return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
-}
-
-ir_node *get_Block_cg_cfgpred(const ir_node *node, int pos)
-{
- assert(is_Block(node) && node->attr.block.in_cg);
- return node->attr.block.in_cg[pos + 1];
-}
-
-void remove_Block_cg_cfgpred_arr(ir_node *node)
-{
- assert(is_Block(node));
- node->attr.block.in_cg = NULL;
-}
-#endif /* INTERPROCEDURAL_VIEW */
-
ir_node *(set_Block_dead)(ir_node *block)
{
return _set_Block_dead(block);
long get_Proj_proj(const ir_node *node)
{
-#ifdef INTERPROCEDURAL_VIEW
- ir_opcode code = get_irn_opcode(node);
-
- if (code == iro_Proj) {
- return node->attr.proj;
- }
- else {
- assert(code == iro_Filter);
- return node->attr.filter.proj;
- }
-#else
assert(is_Proj(node));
return node->attr.proj;
-#endif /* INTERPROCEDURAL_VIEW */
}
void set_Proj_proj(ir_node *node, long proj)
{
-#ifdef INTERPROCEDURAL_VIEW
- ir_opcode code = get_irn_opcode(node);
-
- if (code == iro_Proj) {
- node->attr.proj = proj;
- }
- else {
- assert(code == iro_Filter);
- node->attr.filter.proj = proj;
- }
-#else
assert(is_Proj(node));
node->attr.proj = proj;
-#endif /* INTERPROCEDURAL_VIEW */
}
-/* Returns non-zero if a node is a routine parameter. */
int (is_arg_Proj)(const ir_node *node)
{
return _is_arg_Proj(node);
return get_irn_arity(node);
}
-/*
-void set_Tuple_n_preds(ir_node *node, int n_preds)
-{
- assert(is_Tuple(node));
-}
-*/
-
ir_node *get_Tuple_pred(const ir_node *node, int pos)
{
assert(is_Tuple(node));
set_irn_n(node, pos, pred);
}
-/* Don't use get_irn_arity, get_irn_n in implementation as access
- shall work independent of view!!! */
-void set_Filter_cg_pred_arr(ir_node *node, int arity, ir_node ** in)
-{
- assert(is_Filter(node));
- if (node->attr.filter.in_cg == NULL || arity != ARR_LEN(node->attr.filter.in_cg) - 1) {
- ir_graph *irg = get_irn_irg(node);
- node->attr.filter.in_cg = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1);
- node->attr.filter.backedge = new_backedge_arr(irg->obst, arity);
- node->attr.filter.in_cg[0] = node->in[0];
- }
- memcpy(node->attr.filter.in_cg + 1, in, sizeof(ir_node *) * arity);
-}
-
-void set_Filter_cg_pred(ir_node * node, int pos, ir_node * pred)
-{
- assert(is_Filter(node) && node->attr.filter.in_cg &&
- 0 <= pos && pos < ARR_LEN(node->attr.filter.in_cg) - 1);
- node->attr.filter.in_cg[pos + 1] = pred;
-}
-
-int get_Filter_n_cg_preds(const ir_node *node)
-{
- assert(is_Filter(node) && node->attr.filter.in_cg);
- return (ARR_LEN(node->attr.filter.in_cg) - 1);
-}
-
-ir_node *get_Filter_cg_pred(const ir_node *node, int pos)
-{
- int arity;
- assert(is_Filter(node) && node->attr.filter.in_cg &&
- 0 <= pos);
- arity = ARR_LEN(node->attr.filter.in_cg);
- assert(pos < arity - 1);
- return node->attr.filter.in_cg[pos + 1];
-}
-
int get_ASM_n_input_constraints(const ir_node *node)
{
assert(is_ASM(node));
return is_op_cfopcode(get_irn_op(node));
}
-/* Returns true if the operation manipulates interprocedural control flow:
- CallBegin, EndReg, EndExcept */
-int is_ip_cfop(const ir_node *node)
-{
- return is_ip_cfopcode(get_irn_op(node));
-}
-
/* Returns true if the operation can change the control flow because
of an exception. */
int is_fragile_op(const ir_node *node)
int i, irn_arity;
/* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
- h = irn_arity = get_irn_intra_arity(node);
+ h = irn_arity = get_irn_arity(node);
/* consider all in nodes... except the block if not a control flow. */
for (i = is_cfop(node) ? -1 : 0; i < irn_arity; ++i) {
- ir_node *pred = get_irn_intra_n(node, i);
+ ir_node *pred = get_irn_n(node, i);
if (is_irn_cse_neutral(pred))
h *= 9;
else
* Returns the number of predecessors without the block predecessor.
* Intern version for libFirm.
*/
-static inline int _get_irn_intra_arity(const ir_node *node)
+static inline int _get_irn_arity(const ir_node *node)
{
- assert(node);
return ARR_LEN(node->in) - 1;
}
/**
- * Returns the number of predecessors without the block predecessor.
* Intern version for libFirm.
*/
-static inline int _get_irn_inter_arity(const ir_node *node)
-{
- assert(node);
- if (_get_irn_op(node) == op_Filter) {
- assert(node->attr.filter.in_cg);
- return ARR_LEN(node->attr.filter.in_cg) - 1;
- } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
- return ARR_LEN(node->attr.block.in_cg) - 1;
- }
- return _get_irn_intra_arity(node);
-}
-
-#ifdef INTERPROCEDURAL_VIEW
-/**
- * Returns the number of predecessors without the block predecessor.
- * Intern version for libFirm.
- */
-extern int (*_get_irn_arity)(const ir_node *node);
-
-#else
-
-#define _get_irn_arity(n) _get_irn_intra_arity(n)
-#endif
-
-/**
- * Intern version for libFirm.
- */
-static inline ir_node *_get_irn_intra_n(const ir_node *node, int n)
+static inline ir_node *_get_irn_n(const ir_node *node, int n)
{
ir_node *nn;
- assert(node);
- assert(-1 <= n && n < _get_irn_intra_arity(node));
+ assert(-1 <= n && n < _get_irn_arity(node));
nn = node->in[n + 1];
if (nn == NULL) {
return (node->in[n + 1] = skip_Id(nn));
}
-/**
- * Intern version for libFirm.
- */
-static inline ir_node *_get_irn_inter_n(const ir_node *node, int n)
-{
- assert(node); assert(-1 <= n && n < _get_irn_inter_arity(node));
-
- /* handle Filter and Block specially */
- if (_get_irn_op(node) == op_Filter) {
- assert(node->attr.filter.in_cg);
- return (node->attr.filter.in_cg[n + 1] = skip_Id(node->attr.filter.in_cg[n + 1]));
- } else if (_get_irn_op(node) == op_Block && node->attr.block.in_cg) {
- return (node->attr.block.in_cg[n + 1] = skip_Id(node->attr.block.in_cg[n + 1]));
- }
-
- return _get_irn_intra_n(node, n);
-}
-
/**
* returns a hash value for a node
*/
return (unsigned) get_irn_idx(node);
}
-/**
- * Access to the predecessors of a node.
- * To iterate over the operands iterate from 0 to i < get_irn_arity(),
- * to iterate including the Block predecessor iterate from i = -1 to
- * i < get_irn_arity.
- * If it is a block, the entry -1 is NULL.
- * Intern version for libFirm.
- */
-#ifdef INTERPROCEDURAL_VIEW
-extern ir_node *(*_get_irn_n)(const ir_node *node, int n);
-#else
-#define _get_irn_n(n,i) _get_irn_intra_n(n,i)
-#endif
-
static inline int _get_irn_deps(const ir_node *node) {
return node->deps ? ARR_LEN(node->deps) : 0;
}
return (node->op->opar == oparity_binary);
}
-static inline int _is_Phi(const ir_node *node)
-{
- ir_op *op;
- assert(node);
-
- op = get_irn_op(node);
-#ifdef INTERPROCEDURAL_VIEW
- if (op == op_Filter) return get_interprocedural_view();
-#endif
- return (op == op_Phi);
-}
-
-static inline int _is_Proj(const ir_node *node)
-{
- ir_op *op;
- assert(node);
-
- op = _get_irn_op(node);
-#ifdef INTERPROCEDURAL_VIEW
- if (op == op_Filter) return !get_interprocedural_view();
-#endif
- return (op == op_Proj);
-}
-
static inline int _is_strictConv(const ir_node *node)
{
return _is_Conv(node) && get_Conv_strict(node);
/* this section MUST contain all inline functions */
#define is_ir_node(thing) _is_ir_node(thing)
-#define get_irn_intra_arity(node) _get_irn_intra_arity(node)
-#define get_irn_inter_arity(node) _get_irn_inter_arity(node)
#define get_irn_arity(node) _get_irn_arity(node)
-#define get_irn_intra_n(node, n) _get_irn_intra_n(node, n)
-#define get_irn_inter_n(node, n) _get_irn_inter_n(node, n)
#define get_irn_n(node, n) _get_irn_n(node, n)
#define get_irn_mode(node) _get_irn_mode(node)
#define set_irn_mode(node, mode) _set_irn_mode(node, mode)
new_node->attr.phi.u.backedge = new_backedge_arr(irg->obst, get_irn_arity(new_node));
}
-/**
- * Copies all filter attributes stored in old node to the new node
- */
-static void filter_copy_attr(ir_graph *irg, const ir_node *old_node,
- ir_node *new_node)
-{
- default_copy_attr(irg, old_node, new_node);
- new_node->attr.filter.backedge = new_backedge_arr(irg->obst, get_irn_arity(new_node));
-}
-
/**
* Copies all ASM attributes stored in old node to the new node
*/
case iro_Phi:
ops->copy_attr = phi_copy_attr;
break;
- case iro_Filter:
- ops->copy_attr = filter_copy_attr;
- break;
case iro_ASM:
ops->copy_attr = ASM_copy_attr;
break;
return op->flags & irop_flag_cfopcode;
}
-/**
- * Returns non-zero if the operation manipulates interprocedural control flow:
- * CallBegin, EndReg, EndExcept
- */
-static inline int is_ip_cfopcode(const ir_op *op) {
- return op->flags & irop_flag_ip_cfopcode;
-}
-
/** Returns non-zero if operation is commutative */
static inline int is_op_commutative(const ir_op *op) {
return op->flags & irop_flag_commutative;
return a->attr.proj != b->attr.proj;
} /* node_cmp_attr_Proj */
-/** Compares the attributes of two Filter nodes. */
-static int node_cmp_attr_Filter(ir_node *a, ir_node *b)
-{
- return get_Filter_proj(a) != get_Filter_proj(b);
-} /* node_cmp_attr_Filter */
-
/** Compares the attributes of two Alloc nodes. */
static int node_cmp_attr_Alloc(ir_node *a, ir_node *b)
{
switch (code) {
CASE(Const);
CASE(Proj);
- CASE(Filter);
CASE(Alloc);
CASE(Free);
CASE(SymConst);
(get_irn_mode(a) != get_irn_mode(b))) return 1;
/* compare if a's in and b's in are of equal length */
- irn_arity_a = get_irn_intra_arity(a);
- if (irn_arity_a != get_irn_intra_arity(b))
+ irn_arity_a = get_irn_arity(a);
+ if (irn_arity_a != get_irn_arity(b))
return 1;
if (get_irn_pinned(a) == op_pin_state_pinned) {
/* for pinned nodes, the block inputs must be equal */
- if (get_irn_intra_n(a, -1) != get_irn_intra_n(b, -1))
+ if (get_irn_n(a, -1) != get_irn_n(b, -1))
return 1;
} else if (! get_opt_global_cse()) {
/* for block-local CSE both nodes must be in the same MacroBlock */
/* compare a->in[0..ins] with b->in[0..ins] */
for (i = 0; i < irn_arity_a; ++i) {
- ir_node *pred_a = get_irn_intra_n(a, i);
- ir_node *pred_b = get_irn_intra_n(b, i);
+ ir_node *pred_a = get_irn_n(a, i);
+ ir_node *pred_b = get_irn_n(b, i);
if (pred_a != pred_b) {
/* if both predecessors are CSE neutral they might be different */
if (!is_irn_cse_neutral(pred_a) || !is_irn_cse_neutral(pred_b))
#include "irprog.h"
#include "irtypes.h"
-#include "ircgcons.h"
#include "irtypeinfo.h"
#include "irmemory.h"
anchor_start_block, /**< block the start node will belong to */
anchor_end, /**< end node of this ir_graph */
anchor_start, /**< start node of this ir_graph */
- anchor_end_reg, /**< end node of this ir_graph */
- anchor_end_except, /**< end node of this ir_graph */
anchor_initial_exec, /**< methods initial control flow */
anchor_frame, /**< methods frame */
anchor_tls, /**< pointer to the thread local storage containing all
/* -- states of and access to generated information -- */
irg_phase_state phase_state; /**< The state of construction. */
- ip_view_state ip_view; /**< The state of interprocedural view. */
-
irg_outs_state outs_state; /**< The state of out edges of ir nodes. */
ir_node **ip_outedges; /**< A huge Array that contains all out edges
in interprocedural view. */
#include "irprog.h"
#include "irop_t.h"
#include "irgraph_t.h"
-#include "ircgcons.h"
#include "irvrfy_t.h"
#include "irgwalk.h"
#include "irdump.h"
return 1;
}
-/**
- * verify a Proj(CallBegin) node
- */
-static int verify_node_Proj_CallBegin(ir_node *n, ir_node *p)
-{
- (void) n;
- (void) p;
- return 1;
-}
-
-/**
- * verify a Proj(EndReg) node
- */
-static int verify_node_Proj_EndReg(ir_node *n, ir_node *p)
-{
- (void) n;
- (void) p;
-#ifdef INTERPROCEDURAL_VIEW
- ASSERT_AND_RET(
- (get_irp_ip_view_state() != ip_view_no),
- "EndReg may only appear if ip view is constructed.", 0);
-#endif
- return 1;
-}
-
-/**
- * verify a Proj(EndExcept) node
- */
-static int verify_node_Proj_EndExcept(ir_node *n, ir_node *p)
-{
- (void) n;
- (void) p;
-#ifdef INTERPROCEDURAL_VIEW
- ASSERT_AND_RET(
- (get_irp_ip_view_state() != ip_view_no),
- "EndExcept may only appear if ip view is constructed.", 0);
-#endif
- return 1;
-}
-
/**
* verify a Proj(CopyB) node
*/
return 1;
}
-/**
- * verify a Break node
- */
-static int verify_node_Break(ir_node *n, ir_graph *irg)
-{
- ir_mode *mymode = get_irn_mode(n);
- (void) irg;
-
-#ifdef INTERPROCEDURAL_VIEW
- ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
- "Break may only appear if ip view is constructed.", 0);
-#endif
- ASSERT_AND_RET(
- /* Jmp: BB --> X */
- mymode == mode_X, "Break node", 0
- );
- return 1;
-}
-
/**
* verify a Cond node
*/
return 1;
}
-/**
- * verify a Filter node
- */
-static int verify_node_Filter(ir_node *n, ir_graph *irg)
-{
- (void) n;
- (void) irg;
-#ifdef INTERPROCEDURAL_VIEW
- ASSERT_AND_RET((get_irp_ip_view_state() != ip_view_no),
- "Filter may only appear if ip view is constructed.", 0);
-#endif
- /* We should further do tests as for Proj and Phi. */
- return 1;
-}
-
/**
* verify a Load node
*/
CASE(Start);
CASE(Jmp);
CASE(IJmp);
- CASE(Break);
CASE(Cond);
CASE(Return);
CASE(Raise);
CASE(Conv);
CASE(Cast);
CASE(Phi);
- CASE(Filter);
CASE(Load);
CASE(Store);
CASE(Alloc);
CASE(Alloc);
CASE(Proj);
CASE(Tuple);
- CASE(CallBegin);
- CASE(EndReg);
- CASE(EndExcept);
CASE(CopyB);
CASE(Bound);
default:
void dead_node_elimination(ir_graph *irg)
{
ir_graph *rem;
-#ifdef INTERPROCEDURAL_VIEW
- int rem_ipview = get_interprocedural_view();
-#endif
struct obstack *graveyard_obst = NULL;
struct obstack *rebirth_obst = NULL;
/* Remember external state of current_ir_graph. */
rem = current_ir_graph;
current_ir_graph = irg;
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(0);
-#endif
assert(get_irg_phase_state(irg) != phase_building);
hook_dead_node_elim(irg, 0);
current_ir_graph = rem;
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem_ipview);
-#endif
}
ir_graph_pass_t *dead_node_elimination_pass(const char *name)
return node;
}
- arity = get_irn_intra_arity(node);
+ arity = get_irn_arity(node);
/* check if the node has at least one Phi predecessor */
for (i = 0; i < arity; ++i) {
- ir_node *pred = get_irn_intra_n(node, i);
+ ir_node *pred = get_irn_n(node, i);
ir_node *leader = lookup(pred);
ir_node *trans;
set_nodes_block(nn, get_nodes_block(node));
for (i = 0; i < arity; ++i) {
- ir_node *pred = get_irn_intra_n(node, i);
+ ir_node *pred = get_irn_n(node, i);
ir_node *leader = lookup(pred);
ir_node *trans;
pre_env *env = ctx;
ir_node *value, *expr, *idom, *first_s, *worklist;
block_info *curr_info, *idom_info;
- int pos, arity = get_irn_intra_arity(block);
+ int pos, arity = get_irn_arity(block);
int all_same, by_some, updated;
ir_valueset_iterator_t iter;
int i;
ir_node *res = NULL;
- for (i = get_irn_intra_arity(p->new_node) - 1; i >= 0; --i) {
+ for (i = get_irn_arity(p->new_node) - 1; i >= 0; --i) {
ir_node *pred = get_irn_n(p->new_node, i);
if (pred != p->old_node) {
firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
'''
-class Break(Op):
- mode = "mode_X"
- flags = [ "cfopcode" ]
- pinned = "yes"
-
class Builtin(Op):
ins = [ "mem" ]
arity = "variable"
firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
'''
-class CallBegin(Op):
- ins = [ "ptr" ]
- outs = [ "" ] # TODO
- flags = [ "cfopcode", "ip_cfopcode" ]
- pinned = "yes"
- # TODO: attribute with call...
- attr_struct = "callbegin_attr"
- attrs = [
- dict(
- type = "ir_node*",
- name = "call"
- )
- ]
- java_noconstr = True
-
class Carry(Binop):
flags = [ "commutative" ]
flags = [ "cfopcode" ]
singleton = True
-class EndExcept(Op):
- mode = "mode_X"
- pinned = "yes"
- arity = "dynamic"
- flags = [ "cfopcode", "ip_cfopcode" ]
- singleton = True
-
-class EndReg(Op):
- mode = "mode_X"
- pinned = "yes"
- arity = "dynamic"
- flags = [ "cfopcode", "ip_cfopcode" ]
- singleton = True
-
class Eor(Binop):
flags = [ "commutative" ]
-class Filter(Op):
- ins = [ "pred" ]
- flags = []
- attrs = [
- dict(
- name = "proj",
- type = "long"
- )
- ]
- pinned = "yes"
- attr_struct = "filter_attr"
- attrs_name = "filter"
- java_noconstr = True
-
class Free(Op):
ins = [ "mem", "ptr", "size" ]
mode = "mode_M"
arity = "variable"
flags = []
attr_struct = "phi_attr"
- custom_is = True
java_noconstr = True
init = '''
/* Memory Phis in endless loops must be kept alive.
)
]
attr_struct = "long"
- custom_is = True
class Quot(Op):
ins = [ "mem", "left", "right" ]