Commit b3b65d5e authored by Matthias Braun's avatar Matthias Braun
Browse files

simplify/rework lower_calls interface and code

This was done by removing unnecessary options/options that only
allowed marginal tweakings to improve performance while at the same time
making the interface cumbersome.
parent 56c66ba8
......@@ -420,12 +420,6 @@ FIRM_API ir_node *get_Call_param(const ir_node *node, int pos);
/** Sets the call parameter at position pos. */
FIRM_API void set_Call_param(ir_node *node, int pos, ir_node *param);
/**
* Returns non-zero if a Call is surely a self-recursive Call.
* Beware: if this functions returns 0, the call might be self-recursive!
*/
FIRM_API int is_self_recursive_Call(const ir_node *call);
/** Set, get and remove the callee information for a Call node.
*
* The callee information lists all method entities that can be called
......
......@@ -32,123 +32,6 @@
#include "begin.h"
/**
* A type telling where to add hidden parameters.
*/
typedef enum add_hidden_params {
ADD_HIDDEN_ALWAYS_IN_FRONT = 0, /**< always add hidden parameters in front (default). */
ADD_HIDDEN_ALWAYS_LAST = 1, /**< always add hidden parameters last, did not work for variadic functions. */
ADD_HIDDEN_SMART = 2 /**< add hidden parameters last for non-variadic and first for variadic functions. */
} add_hidden;
/**
* Additional flags for the lowering.
*/
enum lowering_flags {
LF_NONE = 0, /**< no additional flags */
LF_COMPOUND_PARAM = 1, /**< lower calls with compound parameters */
LF_COMPOUND_RETURN = 2, /**< lower calls with compound returns */
LF_RETURN_HIDDEN = 4, /**< return the hidden address instead of void */
LF_SMALL_CMP_IN_REGS = 8 /**< return small compound values in registers */
};
/** Maximum number of registers that can be used to return compound values. */
#define MAX_REGISTER_RET_VAL 2
/**
* A struct containing all control parameters for
* lower_compound_ret_calls().
*/
typedef struct {
int def_ptr_alignment; /**< Default alignment for data pointer. */
unsigned flags; /**< A bitmask of enum lowering_flags. */
add_hidden hidden_params; /**< Where to add hidden parameters. */
/**
* A function returning a pointer type for a given type.
* If this pointer is NULL, a new pointer type is always created.
*/
ir_type *(*find_pointer_type)(ir_type *e_type, ir_mode *mode, int alignment);
/**
* If the LF_SMALL_CMP_IN_REGS flag is set, this function will be called
* to decide, whether a compound value should be returned in registers.
* This function must return the number of used registers and fill in the modes
* of the registers to use. Up to MAX_REGISTER_RET_VAL registers can be used.
*/
int (*ret_compound_in_regs)(ir_type *compound_tp, ir_mode **modes);
} lower_params_t;
/**
* Lower calls with compound parameter and return types.
* This function does the following transformations:
*
* If LF_COMPOUND_PARAM is set:
*
* - Copy compound parameters to a new location on the callers
* stack and transmit the address of this new location
*
* If LF_COMPOUND_RETURN is set:
*
* - Adds a new (hidden) pointer parameter for
* any return compound type. The return type is replaced by void
* or if LOWERING_FLAGS_RETURN_HIDDEN is set by the address.
*
* - Use of the hidden parameters in the function code.
*
* - Change all calls to functions with compound return
* by providing space for the hidden parameter on the callers
* stack.
*
* - Replace a possible block copy after the function call.
*
* General:
*
* - Changes the types of methods and calls to the lowered ones
*
* - lower all method types of existing entities
*
* In pseudo-code, the following transformation is done:
*
@code
struct x ret = func(a, b);
@endcode
*
* is translated into
@code
struct x ret;
func(&ret, a, b);
@endcode
*
* If the function returns only one possible result, the copy-on-return
* optimization is done, ie.
@code
struct x func(a) {
struct x ret;
ret.a = a;
return ret;
}
@endcode
*
* is transformed into
*
@code
void func(struct x *ret, a) {
ret->a = a;
}
@endcode
*
* @param params A structure containing the control parameter for this
* transformation.
*
* During the transformation, pointer types must be created or reused.
* The caller can provide params->find_pointer_type for this task to
* reduce the number of created pointer types.
* If params->find_pointer_type is NULL, new pointer types
* are always created automatically.
*/
FIRM_API void lower_calls_with_compounds(const lower_params_t *params);
/**
* Lower CopyB nodes of size smaller that max_size into Loads/Stores
*/
......
......@@ -29,6 +29,7 @@
#include "irprintf.h"
#include "ircons.h"
#include "irgmod.h"
#include "lower_calls.h"
#include "bitset.h"
#include "debug.h"
......@@ -289,16 +290,8 @@ static int TEMPLATE_get_reg_class_alignment(const arch_register_class_t *cls)
static void TEMPLATE_lower_for_target(void)
{
lower_params_t params = {
4, /* def_ptr_alignment */
LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
NULL, /* find pointer type */
NULL, /* ret_compound_in_regs */
};
/* lower compound param handling */
lower_calls_with_compounds(&params);
lower_calls_with_compounds(LF_RETURN_HIDDEN);
}
static int TEMPLATE_is_mux_allowed(ir_node *sel, ir_node *mux_false,
......
......@@ -30,6 +30,7 @@
#include "ircons.h"
#include "irgmod.h"
#include "irdump.h"
#include "lower_calls.h"
#include "bitset.h"
#include "debug.h"
......@@ -470,16 +471,8 @@ static int amd64_get_reg_class_alignment(const arch_register_class_t *cls)
static void amd64_lower_for_target(void)
{
lower_params_t params = {
4, /* def_ptr_alignment */
LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
NULL, /* find pointer type */
NULL, /* ret_compound_in_regs */
};
/* lower compound param handling */
lower_calls_with_compounds(&params);
lower_calls_with_compounds(LF_RETURN_HIDDEN);
}
static int amd64_is_mux_allowed(ir_node *sel, ir_node *mux_false,
......
......@@ -36,7 +36,7 @@
#include "irgopt.h"
#include "iroptimize.h"
#include "irdump.h"
#include "lowering.h"
#include "lower_calls.h"
#include "error.h"
#include "bitset.h"
......@@ -532,16 +532,8 @@ static void arm_lower_for_target(void)
{
size_t i, n_irgs = get_irp_n_irgs();
lower_params_t params = {
4, /* def_ptr_alignment */
LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
NULL, /* find pointer type */
NULL, /* ret_compound_in_regs */
};
/* lower compound param handling */
lower_calls_with_compounds(&params);
lower_calls_with_compounds(LF_RETURN_HIDDEN);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
......
......@@ -52,6 +52,7 @@
#include "instrument.h"
#include "iropt_t.h"
#include "lower_dw.h"
#include "lower_calls.h"
#include "../beabi.h"
#include "../beirg.h"
......@@ -2011,13 +2012,6 @@ static void ia32_lower_for_target(void)
ia32_create_set,
0, /* don't lower direct compares */
};
lower_params_t params = {
4, /* def_ptr_alignment */
LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
NULL, /* find pointer type */
NULL, /* ret_compound_in_regs */
};
/* perform doubleword lowering */
lwrdw_param_t lower_dw_params = {
......@@ -2028,7 +2022,7 @@ static void ia32_lower_for_target(void)
};
/* lower compound param handling */
lower_calls_with_compounds(&params);
lower_calls_with_compounds(LF_RETURN_HIDDEN);
ir_prepare_dw_lowering(&lower_dw_params);
ir_lower_dw_ops();
......
......@@ -39,6 +39,7 @@
#include "irdump.h"
#include "lowering.h"
#include "lower_dw.h"
#include "lower_calls.h"
#include "bitset.h"
#include "debug.h"
......@@ -547,14 +548,7 @@ static void sparc_lower_for_target(void)
sparc_create_set,
0,
};
lower_params_t params = {
4, /* def_ptr_alignment */
LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
ADD_HIDDEN_ALWAYS_IN_FRONT, /* hidden_params */
NULL, /* find pointer type */
NULL, /* ret_compound_in_regs */
};
lower_calls_with_compounds(&params);
lower_calls_with_compounds(LF_RETURN_HIDDEN);
sparc_lower_64bit();
......
......@@ -1071,23 +1071,6 @@ void remove_Call_callee_arr(ir_node *node)
node->attr.call.callee_arr = NULL;
}
/*
* Returns non-zero if a Call is surely a self-recursive Call.
* Beware: if this functions returns 0, the call might be self-recursive!
*/
int is_self_recursive_Call(const ir_node *call)
{
const ir_node *callee = get_Call_ptr(call);
if (is_SymConst_addr_ent(callee)) {
const ir_entity *ent = get_SymConst_entity(callee);
const ir_graph *irg = get_entity_irg(ent);
if (irg == get_irn_irg(call))
return 1;
}
return 0;
}
/* Checks for upcast.
*
* Returns true if the Cast node casts a class type to a super type.
......
This diff is collapsed.
/*
* Copyright (C) 1995-2011 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 Lowering of calls with compound arguments
* @author Michael Beck
* @version $Id$
*/
#ifndef FIRM_LOWER_CALLS_H
#define FIRM_LOWER_CALLS_H
#include "firm_types.h"
/**
* Additional flags for the lowering.
*/
typedef enum compound_call_lowering_flags {
LF_NONE = 0, /**< no additional flags */
LF_RETURN_HIDDEN = 1 << 0, /**< return the hidden address instead of void */
} compound_call_lowering_flags;
ENUM_BITSET(compound_call_lowering_flags)
/**
* Lower calls with compound parameter and return types.
* This function does the following transformations:
*
* If LF_COMPOUND_PARAM is set:
*
* - Copy compound parameters to a new location on the callers
* stack and transmit the address of this new location
*
* If LF_COMPOUND_RETURN is set:
*
* - Adds a new (hidden) pointer parameter for
* any return compound type. The return type is replaced by void
* or if LOWERING_FLAGS_RETURN_HIDDEN is set by the address.
*
* - Use of the hidden parameters in the function code.
*
* - Change all calls to functions with compound return
* by providing space for the hidden parameter on the callers
* stack.
*
* - Replace a possible block copy after the function call.
*
* General:
*
* - Changes the types of methods and calls to the lowered ones
*
* - lower all method types of existing entities
*
* In pseudo-code, the following transformation is done:
*
@code
struct x ret = func(a, b);
@endcode
*
* is translated into
@code
struct x ret;
func(&ret, a, b);
@endcode
*
* If the function returns only one possible result, the copy-on-return
* optimization is done, ie.
@code
struct x func(a) {
struct x ret;
ret.a = a;
return ret;
}
@endcode
*
* is transformed into
*
@code
void func(struct x *ret, a) {
ret->a = a;
}
@endcode
*/
void lower_calls_with_compounds(compound_call_lowering_flags flags);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment