return irn == cg->noreg_gp || irn == cg->noreg_xmm || irn == cg->noreg_vfp;
}
-void ia32_pre_transform_phase(ia32_code_gen_t *cg) {
- /*
- We need to transform the consts twice:
- - the psi condition tree transformer needs existing constants to be ia32 constants
- - the psi condition tree transformer inserts new firm constants which need to be transformed
- */
- //ia32_transform_all_firm_consts(cg);
- irg_walk_graph(cg->irg, NULL, ia32_transform_psi_cond_tree, cg);
- //ia32_transform_all_firm_consts(cg);
-}
-
/********************************************************************************************************
* _____ _ _ ____ _ _ _ _ _
* | __ \ | | | | / __ \ | | (_) (_) | | (_)
/**
* Tries to replace a TestJmp by a CJmp or CJmpAM (in case of And)
*/
-static void ia32_optimize_TestJmp(ir_node *irn, ia32_code_gen_t *cg) {
+static void ia32_optimize_TestJmp(ir_node *irn)
+{
ir_node *cand = ia32_determine_cjmp_cand(irn, is_TestJmp_cand);
int replace = 0;
/**
* Tries to replace a CondJmp by a CJmpAM
*/
-static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) {
+static void ia32_optimize_CondJmp(ir_node *irn)
+{
ir_node *cand = ia32_determine_cjmp_cand(irn, is_CondJmp_cand);
int replace = 0;
// create memory proj
mem_proj = new_r_Proj(irg, block, push, mode_M, pn_ia32_Push_M);
- sched_add_before(irn, mem_proj);
// use the memproj now
exchange(store, mem_proj);
/* AMD CPUs want explicit compare before conditional jump */
if (! ARCH_AMD(cg->opt_arch)) {
if (is_ia32_TestJmp(irn))
- ia32_optimize_TestJmp(irn, cg);
+ ia32_optimize_TestJmp(irn);
else if (is_ia32_CondJmp(irn))
- ia32_optimize_CondJmp(irn, cg);
+ ia32_optimize_CondJmp(irn);
}
if (be_is_IncSP(irn)) {
* @param irn The irn to check
* return 1 if irn is a candidate, 0 otherwise
*/
-static int is_addr_candidate(const ir_node *irn) {
+static int is_addr_candidate(const ir_node *irn)
+{
#ifndef AGGRESSIVE_AM
const ir_node *block = get_nodes_block(irn);
ir_node *left, *right;
}
#endif
+ (void) irn;
return 1;
}
* @param irn The irn to check
* return 0 if irn is no candidate, 1 if left load can be used, 2 if right one, 3 for both
*/
-static ia32_am_cand_t is_am_candidate(ia32_code_gen_t *cg, heights_t *h, const ir_node *block, ir_node *irn) {
+static ia32_am_cand_t is_am_candidate(heights_t *h, const ir_node *block, ir_node *irn) {
ir_node *in, *load, *other, *left, *right;
int is_cand = 0, cand;
int arity;
/* ok, we can create a new LEA */
if (dolea) {
res = new_rd_ia32_Lea(dbg_info, irg, block, base, index);
+ /* we don't want stuff before the barrier... */
+ if(be_is_NoReg(cg, base) && be_is_NoReg(cg, index)) {
+ add_irn_dep(res, get_irg_frame(irg));
+ }
/* add the old offset of a previous LEA */
add_ia32_am_offs_int(res, offs);
}
}
-static void optimize_conv_store(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_conv_store(ir_node *node)
{
ir_node *pred;
ir_mode *conv_mode;
}
}
-static void optimize_load_conv(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_load_conv(ir_node *node)
{
ir_node *pred, *predpred;
ir_mode *load_mode;
if(get_mode_size_bits(conv_mode) < get_mode_size_bits(load_mode))
return;
+ if(get_mode_sign(conv_mode) != get_mode_sign(load_mode)) {
+ /* change the load if it has only 1 user */
+ if(get_irn_n_edges(pred) == 1) {
+ ir_mode *newmode;
+ if(get_mode_sign(conv_mode)) {
+ newmode = find_signed_mode(load_mode);
+ } else {
+ newmode = find_unsigned_mode(load_mode);
+ }
+ assert(newmode != NULL);
+ set_ia32_ls_mode(predpred, newmode);
+ } else {
+ /* otherwise we have to keep the conv */
+ return;
+ }
+ }
+
/* kill the conv */
exchange(node, pred);
}
-static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node)
+static void optimize_conv_conv(ir_node *node)
{
ir_node *pred;
ir_mode *pred_mode;
if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node))
return;
- pred = get_irn_n(node, 2);
+ assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val);
+ pred = get_irn_n(node, n_ia32_Conv_I2I_val);
if(!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred))
return;
if(get_mode_size_bits(conv_mode) < get_mode_size_bits(pred_mode))
return;
+ /* we can't eliminate an upconv signed->unsigned */
+ if (get_mode_size_bits(conv_mode) != get_mode_size_bits(pred_mode) &&
+ !get_mode_sign(conv_mode) && get_mode_sign(pred_mode))
+ return;
+
/* kill the conv */
exchange(node, pred);
}
{
ia32_code_gen_t *cg = env;
- optimize_load_conv(cg, node);
- optimize_conv_store(cg, node);
- optimize_conv_conv(cg, node);
+ optimize_load_conv(node);
+ optimize_conv_store(node);
+ optimize_conv_conv(node);
optimize_lea(cg, node);
}
if (get_ia32_am_support(irn) == ia32_am_None)
return;
- cand = is_am_candidate(cg, h, block, irn);
+ cand = is_am_candidate(h, block, irn);
if (cand == IA32_AM_CAND_NONE)
return;