libFirm
Transformations and Optimizations

Modules

 Flags
 Flags to customize the behavior of libfirm.
 
 Graph Transformations
 
 Local Optimizations
 

Macros

#define osr_flag_default   osr_flag_lftr_with_ov_check
 default setting More...
 
#define DEFAULT_CLONE_THRESHOLD   20
 A default threshold. More...
 

Typedefs

typedef struct ir_settings_arch_dep_t ir_settings_arch_dep_t
 
typedef int(* check_alloc_entity_func) (ir_entity *ent)
 A callback that checks whether a entity is an allocation routine. More...
 
typedef int(* arch_allow_ifconv_func) (ir_node *sel, ir_node *mux_false, ir_node *mux_true)
 This function is called to evaluate, if a mux(sel, mux_false, mux_true) should be built for the current architecture. More...
 
typedef void(* opt_ptr) (ir_graph *irg)
 pointer to an optimization function More...
 
typedef ident *(* compilerlib_name_mangle_t) (ident *id, ir_type *mt)
 Type of callbacks for creating entities of the compiler library. More...
 

Enumerations

enum  arch_dep_opts_t { arch_dep_none = 0, arch_dep_mul_to_shift = 1u << 0, arch_dep_div_by_const = 1u << 1, arch_dep_mod_by_const = 1u << 2 }
 Optimization flags. More...
 
enum  osr_flags { osr_flag_none = 0, osr_flag_lftr_with_ov_check = 1, osr_flag_ignore_x86_shift = 2, osr_flag_keep_reg_pressure = 4 }
 Possible flags for the Operator Scalar Replacement. More...
 

Functions

void arch_dep_set_opts (arch_dep_opts_t opts)
 Sets the optimizations that shall be applied. More...
 
void optimize_cf (ir_graph *irg)
 Control flow optimization. More...
 
void opt_jumpthreading (ir_graph *irg)
 Perform path-sensitive jump threading on the given graph. More...
 
void opt_bool (ir_graph *irg)
 Simplifies boolean expression in the given ir graph. More...
 
void conv_opt (ir_graph *irg)
 Reduces the number of Conv nodes in the given ir graph. More...
 
void optimize_funccalls (void)
 Optimize function calls by handling const functions. More...
 
void do_gvn_pre (ir_graph *irg)
 Does Partial Redundancy Elimination combined with Global Value Numbering. More...
 
void opt_if_conv (ir_graph *irg)
 Perform If conversion on a graph. More...
 
void opt_if_conv_cb (ir_graph *irg, arch_allow_ifconv_func callback)
 Perform If conversion on a graph - callback version. More...
 
void opt_parallelize_mem (ir_graph *irg)
 Tries to reduce dependencies for memory nodes where possible by parallelizing them and synchronizing with Sync nodes. More...
 
ir_nodecan_replace_load_by_const (const ir_node *load, ir_node *c)
 Check if we can replace the load by a given const from the const code irg. More...
 
void optimize_load_store (ir_graph *irg)
 Load/Store optimization. More...
 
void combine_memops (ir_graph *irg)
 Combine adjacent "small" load/store operations into bigger ones. More...
 
void opt_ldst (ir_graph *irg)
 New experimental alternative to optimize_load_store. More...
 
void opt_frame_irg (ir_graph *irg)
 Optimize the frame type of an irg by removing never touched entities. More...
 
void opt_osr (ir_graph *irg, unsigned flags)
 Performs the Operator Scalar Replacement optimization and linear function test replacement for loop control. More...
 
void remove_phi_cycles (ir_graph *irg)
 Removes useless Phi cycles, i.e cycles of Phi nodes with only one non-Phi node. More...
 
void proc_cloning (float threshold)
 Performs procedure cloning. More...
 
void optimize_reassociation (ir_graph *irg)
 Reassociation. More...
 
void normalize_one_return (ir_graph *irg)
 Normalize the Returns of a graph by creating a new End block with One Return(Phi). More...
 
void normalize_n_returns (ir_graph *irg)
 Normalize the Returns of a graph by moving the Returns upwards as much as possible. More...
 
void scalar_replacement_opt (ir_graph *irg)
 Performs the scalar replacement optimization. More...
 
void opt_tail_rec_irg (ir_graph *irg)
 Optimizes tail-recursion calls by converting them into loops. More...
 
void combo (ir_graph *irg)
 CLiff Click's combo algorithm from "Combining Analyses, combining Optimizations". More...
 
void inline_functions (unsigned maxsize, int inline_threshold, opt_ptr after_inline_opt)
 Heuristic inliner. More...
 
void shape_blocks (ir_graph *irg)
 Combines congruent blocks into one. More...
 
void do_loop_inversion (ir_graph *irg)
 Perform loop inversion on a given graph. More...
 
void do_loop_unrolling (ir_graph *irg)
 Perform loop unrolling on a given graph. More...
 
void do_loop_peeling (ir_graph *irg)
 Perform loop peeling on a given graph. More...
 
void garbage_collect_entities (void)
 Removes all entities which are unused. More...
 
void dead_node_elimination (ir_graph *irg)
 Performs dead node elimination by copying the ir graph to a new obstack. More...
 
void place_code (ir_graph *irg)
 Code Placement. More...
 
void occult_consts (ir_graph *)
 This optimization finds values where the bits are either constant or irrelevant and exchanges them for a corresponding constant. More...
 
int value_not_null (const ir_node *n, const ir_node **confirm)
 Returns true if the value n is known not be zero/null. More...
 
ir_tarvalcomputed_value_Cmp_Confirm (ir_node *left, ir_node *right, ir_relation relation)
 Returns the value of a Cmp if one or both predecessors are Confirm nodes. More...
 
void set_compilerlib_name_mangle (compilerlib_name_mangle_t cb)
 Sets the compilerlib entity creation callback that is used to create compilerlib function entities. More...
 
compilerlib_name_mangle_t get_compilerlib_name_mangle (void)
 Returns the compilerlib entity creation callback. More...
 
ir_entitycreate_compilerlib_entity (ident *id, ir_type *mt)
 Constructs the entity for a given function using the current compilerlib entity creation callback. More...
 

Detailed Description

Macro Definition Documentation

#define DEFAULT_CLONE_THRESHOLD   20

A default threshold.

Definition at line 287 of file iroptimize.h.

#define osr_flag_default   osr_flag_lftr_with_ov_check

default setting

Definition at line 214 of file iroptimize.h.

Typedef Documentation

typedef int(* arch_allow_ifconv_func) (ir_node *sel, ir_node *mux_false, ir_node *mux_true)

This function is called to evaluate, if a mux(sel, mux_false, mux_true) should be built for the current architecture.

If it returns non-zero, a mux is created, else the code is not modified.

Parameters
selA selector of a Cond.
phi_listphi node to be converted
iFirst data predecessor involved in if conversion
jSecond data predecessor involved in if conversion

Definition at line 108 of file iroptimize.h.

typedef int(* check_alloc_entity_func) (ir_entity *ent)

A callback that checks whether a entity is an allocation routine.

Definition at line 60 of file iroptimize.h.

typedef ident*(* compilerlib_name_mangle_t) (ident *id, ir_type *mt)

Type of callbacks for creating entities of the compiler library.

Definition at line 514 of file iroptimize.h.

Definition at line 34 of file irarch.h.

typedef void(* opt_ptr) (ir_graph *irg)

pointer to an optimization function

Definition at line 399 of file iroptimize.h.

Enumeration Type Documentation

Optimization flags.

Enumerator
arch_dep_none 
arch_dep_mul_to_shift 

optimize Mul into Shift/Add/Sub

arch_dep_div_by_const 

optimize Div into Shift/Add/Mulh

arch_dep_mod_by_const 

optimize Mod into Shift/Add/Mulh

Definition at line 26 of file irarch.h.

enum osr_flags

Possible flags for the Operator Scalar Replacement.

Enumerator
osr_flag_none 

no additional flags

osr_flag_lftr_with_ov_check 

do linear function test replacement only if no overflow can occur.

osr_flag_ignore_x86_shift 

ignore Multiplications by 2, 4, 8

osr_flag_keep_reg_pressure 

do NOT increase register pressure by introducing new induction variables.

Definition at line 204 of file iroptimize.h.

Function Documentation

void arch_dep_set_opts ( arch_dep_opts_t  opts)

Sets the optimizations that shall be applied.

Parameters
optsAn optimization bit mask.
ir_node* can_replace_load_by_const ( const ir_node load,
ir_node c 
)

Check if we can replace the load by a given const from the const code irg.

Parameters
loadthe load to replace
cthe constant
Returns
if the modes match or can be transformed using a reinterpret cast returns a copy of the constant (possibly Conv'ed) in the graph where the load is.
void combine_memops ( ir_graph irg)

Combine adjacent "small" load/store operations into bigger ones.

void combo ( ir_graph irg)

CLiff Click's combo algorithm from "Combining Analyses, combining Optimizations".

Does conditional constant propagation, unreachable code elimination and optimistic global value numbering at once.

Parameters
irgthe graph to run on
ir_tarval* computed_value_Cmp_Confirm ( ir_node left,
ir_node right,
ir_relation  relation 
)

Returns the value of a Cmp if one or both predecessors are Confirm nodes.

Parameters
leftthe left operand of the Cmp
rightthe right operand of the Cmp
relationthe compare relation
void conv_opt ( ir_graph irg)

Reduces the number of Conv nodes in the given ir graph.

Parameters
irgthe graph
ir_entity* create_compilerlib_entity ( ident id,
ir_type mt 
)

Constructs the entity for a given function using the current compilerlib entity creation callback.

Parameters
idthe identifier of the compilerlib function
mtthe method type of the compilerlib function
void dead_node_elimination ( ir_graph irg)

Performs dead node elimination by copying the ir graph to a new obstack.

The major intention of this pass is to free memory occupied by dead nodes and outdated analyzes information. Further this function removes Bad predecessors from Blocks and the corresponding inputs to Phi nodes. This opens optimization potential for other optimizations. Further this phase reduces dead Block<->Jmp self-cycles to Bad nodes.

Dead_node_elimination is only performed if options `optimize' and `opt_dead_node_elimination' are set. The graph may not be in state phase_building. The outs data structure is freed, the outs state set to outs_none. Backedge information is conserved. Removes old attributes of nodes. Sets link field to NULL. Callee information must be freed (irg_callee_info_none).

Parameters
irgThe graph to be optimized.
void do_gvn_pre ( ir_graph irg)

Does Partial Redundancy Elimination combined with Global Value Numbering.

Can be used to replace place_code() completely.

Based on VanDrunen and Hosking 2004.

Parameters
irgthe graph
void do_loop_inversion ( ir_graph irg)

Perform loop inversion on a given graph.

Loop inversion transforms a head controlled loop (like while(...) {} and for(...) {}) into a foot controlled loop (do {} while(...)).

void do_loop_peeling ( ir_graph irg)

Perform loop peeling on a given graph.

void do_loop_unrolling ( ir_graph irg)

Perform loop unrolling on a given graph.

Loop unrolling multiplies the number loop completely by a number found through a heuristic.

void garbage_collect_entities ( void  )

Removes all entities which are unused.

Unused entities have ir_visibility_local and are not used directly or indirectly through entities/code visible outside the compilation unit. This is usually conservative than gc_irgs, but does not respect properties of object-oriented programs.

compilerlib_name_mangle_t get_compilerlib_name_mangle ( void  )

Returns the compilerlib entity creation callback.

void inline_functions ( unsigned  maxsize,
int  inline_threshold,
opt_ptr  after_inline_opt 
)

Heuristic inliner.

Calculates a benefice value for every call and inlines those calls with a value higher than the threshold.

Parameters
maxsizeDo not inline any calls if a method has more than maxsize firm nodes. It may reach this limit by inlining.
inline_thresholdinlining threshold
after_inline_optoptimizations performed immediately after inlining some calls
void normalize_n_returns ( ir_graph irg)

Normalize the Returns of a graph by moving the Returns upwards as much as possible.

This might be preferred for code generation.

In pseudocode, it means:

if (a) res = b; else res = c; return res;

is transformed into

if (a) return b; else return c;

void normalize_one_return ( ir_graph irg)

Normalize the Returns of a graph by creating a new End block with One Return(Phi).

This is the preferred input for the if-conversion.

In pseudocode, it means:

if (a) return b; else return c;

is transformed into

if (a) res = b; else res = c; return res;

void occult_consts ( ir_graph )

This optimization finds values where the bits are either constant or irrelevant and exchanges them for a corresponding constant.

void opt_bool ( ir_graph irg)

Simplifies boolean expression in the given ir graph.

eg. x < 5 && x < 6 becomes x < 5

Parameters
irgthe graph
void opt_frame_irg ( ir_graph irg)

Optimize the frame type of an irg by removing never touched entities.

Parameters
irgThe graph whose frame type will be optimized

This function did not change the graph, only its frame type. The layout state of the frame type will be set to layout_undefined if entities were removed.

void opt_if_conv ( ir_graph irg)

Perform If conversion on a graph.

Parameters
irgThe graph.

Cannot handle blocks with Bad control predecessors, so call it after control flow optimization.

void opt_if_conv_cb ( ir_graph irg,
arch_allow_ifconv_func  callback 
)

Perform If conversion on a graph - callback version.

Parameters
irgThe graph.
callbackThe predicate.

Like above, but let the caller decide about valid transformations by supplying a predicate function.

void opt_jumpthreading ( ir_graph irg)

Perform path-sensitive jump threading on the given graph.

Parameters
irgthe graph
void opt_ldst ( ir_graph irg)

New experimental alternative to optimize_load_store.

Based on a dataflow analysis, so load/stores are moved out of loops where possible

void opt_osr ( ir_graph irg,
unsigned  flags 
)

Performs the Operator Scalar Replacement optimization and linear function test replacement for loop control.

Parameters
irgthe graph which should be optimized
flagsset of osr_flags

The linear function replacement test is controlled by the flags. If the osr_flag_lftr_with_ov_check is set, the replacement is only done if do overflow can occur. Otherwise it is ALWAYS done which might be insecure.

For instance:

for (i = 0; i < 100; ++i)

might be replaced by

for (i = 0; i < 400; i += 4)

But

for (i = 0; i < 0x7FFFFFFF; ++i)

will not be replaced by

for (i = 0; i < 0xFFFFFFFC; i += 4)

because of overflow.

More bad cases:

for (i = 0; i <= 0xF; ++i)

will NOT be transformed into

for (i = 0xFFFFFFF0; i <= 0xFFFFFFFF; ++i)

although here is no direct overflow. The OV occurs when the ++i is executed (and would created an endless loop here!).

For the same reason, a loop

for (i = 0; i <= 9; i += x)

will NOT be transformed because we cannot estimate whether an overflow might happen adding x.

Note that i < a + 400 is also not possible with the current implementation although this might be allowed by other compilers...

Note further that tests for equality can be handled some simpler (but are not implemented yet).

This algorithm destroys the link field of nodes.

void opt_parallelize_mem ( ir_graph irg)

Tries to reduce dependencies for memory nodes where possible by parallelizing them and synchronizing with Sync nodes.

Parameters
irgthe graph where memory operations should be parallelized
void opt_tail_rec_irg ( ir_graph irg)

Optimizes tail-recursion calls by converting them into loops.

Depends on the flag opt_tail_recursion. Currently supports the following forms:

  • return func();
  • return x + func();
  • return func() - x;
  • return x * func();
  • return -func();

Does not work for Calls that use the exception stuff.

Parameters
irgthe graph to be optimized
void optimize_cf ( ir_graph irg)

Control flow optimization.

Removes empty blocks doing if simplifications and loop simplifications. A block is empty if it contains only a Jmp node and Phi nodes. Merges single entry single exit blocks with their predecessor and propagates dead control flow by calling equivalent_node(). Independent of compiler flag it removes Tuples from cf edges, Bad predecessors from Blocks and Phis, and unnecessary predecessors of End. Destroys backedge information.

void optimize_funccalls ( void  )

Optimize function calls by handling const functions.

This optimization first detects all "const functions", i.e., IR graphs that neither read nor write memory (and hence did not create exceptions, as these use memory in Firm).

The result of calls to such functions depends only on its arguments, hence those calls are no more pinned.

This is a rather strong criteria, so do not expect that a lot of functions will be found. Moreover, all of them might already be inlined if inlining is activated. Anyway, it might be good for handling builtin's even if the later read/write memory (but we know how).

This optimization reads the irg_const_function property of entities, and sets the irg_const_function property of graphs.

If callee information is valid, we also optimize polymorphic Calls.

void optimize_load_store ( ir_graph irg)

Load/Store optimization.

Removes redundant non-volatile Loads and Stores. May introduce Bad nodes if exceptional control flow is removed. The following cases are optimized:

Load without result: A Load which has only a memory use is removed.

Load after Store: A Load after a Store is removed, if the Load doesn't have an exception handler OR is in the same block as the Store.

Load after Load: A Load after a Load is removed, if the Load doesn't have an exception handler OR is in the same block as the previous Load.

Store before Store: A Store immediately before another Store in the same block is removed, if the Store doesn't have an exception handler.

Store after Load: A Store after a Load is removed, if the Store doesn't have an exception handler.

void optimize_reassociation ( ir_graph irg)

Reassociation.

Applies Reassociation rules to integer expressions. Beware: Works only if integer overflow might be ignored, as for C, Java and for address expression. Works only if Constant folding is activated.

Uses loop information to detect loop-invariant (i.e. constant inside the loop) values.

See Muchnik 12.3.1 Algebraic Simplification and Reassociation of Addressing Expressions.

void place_code ( ir_graph irg)

Code Placement.

Pins all floating nodes to a block where they will be executed only if needed. Depends on the flag opt_global_cse. Graph may not be in phase_building. Does not schedule control dead code. Uses dominator information which it computes if the irg is not in state dom_consistent. Destroys the out information as it moves nodes to other blocks. Optimizes Tuples in Control edges.

Call remove_critical_cf_edges() before place_code(). This normalizes the control flow graph so that for all operations a basic block exists where they can be optimally placed.

void proc_cloning ( float  threshold)

Performs procedure cloning.

Evaluate a heuristic weight for every Call(..., Const, ...). If the weight is bigger than threshold, clone the entity and fix the calls.

Parameters
thresholdthe threshold for cloning

The threshold is an estimation of how many instructions are saved when executing a cloned method. If threshold is 0.0, every possible call is cloned.

void remove_phi_cycles ( ir_graph irg)

Removes useless Phi cycles, i.e cycles of Phi nodes with only one non-Phi node.

This is automatically done in opt_osr(), so there is no need to call it additionally.

Parameters
irgthe graph which should be optimized

This algorithm destroys the link field of nodes.

void scalar_replacement_opt ( ir_graph irg)

Performs the scalar replacement optimization.

Replaces local compound entities (like structures and arrays) with atomic values if possible. Does not handle classes yet.

Parameters
irgthe graph which should be optimized
void set_compilerlib_name_mangle ( compilerlib_name_mangle_t  cb)

Sets the compilerlib entity creation callback that is used to create compilerlib function entities.

Parameters
cbthe new compilerlib entity creation callback
void shape_blocks ( ir_graph irg)

Combines congruent blocks into one.

Parameters
irgThe IR-graph to optimize.
int value_not_null ( const ir_node n,
const ir_node **  confirm 
)

Returns true if the value n is known not be zero/null.

Parameters
na node representing the value
confirmif n is confirmed to be != 0, returns the the Confirm-node, else NULL