#include "benode_t.h"
#include "bechordal_t.h"
-#define REMAT
/* This enables re-computation of values. Current state: Unfinished and buggy. */
#undef BUGGY_REMAT
/**
* Searchs the schedule backwards until we reach the first use or def of a
* value or a phi.
- * Returns the node before this node (so that you can do sched_add_before)
+ * Returns the node after this node (so that you can do sched_add_before)
*/
static ir_node *find_last_use_def(spill_env_t *env, ir_node *block, ir_node *value) {
ir_node *node, *last;
for(i = 0, arity = get_irn_arity(node); i < arity; ++i) {
ir_node *arg = get_irn_n(node, i);
if(arg == value) {
- return skip_projs(node);
+ return skip_projs(last);
}
}
last = node;
return res;
}
-#ifdef REMAT
-
#ifdef BUGGY_REMAT
/**
* @param spilled the node that was spilled
* @param reloader a irn that requires a reload
*/
-static int check_remat_conditions(spill_env_t *senv, ir_node *spill, ir_node *spilled, ir_node *reloader) {
+static int check_remat_conditions(spill_env_t *senv, ir_node *spilled, ir_node *reloader) {
int pos, max;
/* check for 'normal' spill and general remat condition */
- if (!be_is_Spill(spill) || !arch_irn_is(senv->chordal_env->birg->main_env->arch_env, spilled, rematerializable))
+ if (!arch_irn_is(senv->chordal_env->birg->main_env->arch_env, spilled, rematerializable))
return 0;
/* check availability of original arguments */
* @param spilled the node that was spilled
* @param reloader a irn that requires a reload
*/
-static int check_remat_conditions(spill_env_t *senv, ir_node *spill, ir_node *spilled, ir_node *reloader) {
+static int check_remat_conditions(spill_env_t *senv, ir_node *spilled, ir_node *reloader) {
const arch_env_t *aenv = senv->chordal_env->birg->main_env->arch_env;
return get_irn_arity(spilled) == 0 &&
- be_is_Spill(spill) &&
arch_irn_is(aenv, spilled, rematerializable);
}
#endif /* BUGGY_REMAT */
-#endif /* REMAT */
-
/**
* Re-materialize a node.
*
return res;
}
-void be_spill_phi(spill_env_t *env, ir_node *node) {
+static place_copies_for_phi(spill_env_t *env, ir_node* node) {
int i, arity;
assert(is_Phi(node));
- pset_insert_ptr(env->mem_phis, node);
-
/* We have to place copy nodes in the predecessor blocks to temporarily
* produce new values that get separate spill slots
*/
}
}
+void be_place_copies(spill_env_t *env) {
+ ir_node *node;
+
+ foreach_pset(env->mem_phis, node) {
+ place_copies_for_phi(env, node);
+ }
+}
+
+void be_spill_phi(spill_env_t *env, ir_node *node) {
+ spill_ctx_t *spill_ctx;
+
+ assert(is_Phi(node));
+
+ pset_insert_ptr(env->mem_phis, node);
+
+ // remove spill context for this phi (if there was one)
+ spill_ctx = be_get_spill_ctx(env->spill_ctxs, node, node);
+ if(spill_ctx != NULL) {
+ spill_ctx->spill = NULL;
+ }
+}
+
void be_insert_spills_reloads(spill_env_t *env) {
const arch_env_t *arch_env = env->chordal_env->birg->main_env->arch_env;
- ir_node *node;
+ //ir_node *node;
spill_info_t *si;
+#if 0
+ // Matze: This should be pointless as beladies fix_block_borders
+ // should result in the same
DBG((env->dbg, LEVEL_1, "Reloads for mem-phis:\n"));
foreach_pset(env->mem_phis, node) {
const ir_edge_t *e;
}
}
}
+#endif
/* process each spilled node */
DBG((env->dbg, LEVEL_1, "Insert spills and reloads:\n"));
for(rld = si->reloaders; rld; rld = rld->next) {
ir_node *new_val;
- /* the spill for this reloader */
- ir_node *spill = be_spill_node(env, si->spilled_node);
-
-#ifdef REMAT
- if (check_remat_conditions(env, spill, si->spilled_node, rld->reloader)) {
+ if (check_remat_conditions(env, si->spilled_node, rld->reloader)) {
new_val = do_remat(env, si->spilled_node, rld->reloader);
- } else
-#endif
+ } else {
+ /* the spill for this reloader */
+ ir_node *spill = be_spill_node(env, si->spilled_node);
+
/* do a reload */
new_val = be_reload(arch_env, env->cls, rld->reloader, mode, spill);
+ }
DBG((env->dbg, LEVEL_1, " %+F of %+F before %+F\n", new_val, si->spilled_node, rld->reloader));
pset_insert_ptr(values, new_val);
- assign a new offset to this slot
- xor find another slot to coalesce with */
used_slots = 0;
- for (i=0; i<size; ++i) { /* for each spill slot */
+ for (i=0; i<size; ++i) {
+ /* for each spill slot */
ir_node *n1;
int tgt_slot = -1;
if (! e) {
char buf[64];
snprintf(buf, sizeof(buf), "spill_slot_type_%s", get_mode_name(ss->largest_mode));
+ buf[sizeof(buf) - 1] = '\0';
res = new_type_primitive(new_id_from_str(buf), ss->largest_mode);
set_type_alignment_bytes(res, ss->align);
pmap_insert(types, ss->largest_mode, res);
*/
static void assign_entities(ss_env_t *ssenv, int n_slots, spill_slot_t *ss[]) {
int i, offset, frame_align;
- ir_type *frame = get_irg_frame_type(ssenv->cenv->irg);
+ ir_type *frame;
+
+ /* do not align the frame if no spill slots are needed */
+ if (n_slots <= 0)
+ return;
+
+ frame = get_irg_frame_type(ssenv->cenv->irg);
/* aligning by increasing frame size */
- offset = get_type_size_bits(frame) / 8;
+ offset = get_type_size_bytes(frame);
offset = round_up2(offset, ALIGN_SPILL_AREA);
- set_type_size_bytes(frame, -1);
/* create entities and assign offsets according to size and alignment*/
for (i = 0; i < n_slots; ++i) {
/* build entity */
snprintf(buf, sizeof(buf), "spill_slot_%d", i);
+ buf[sizeof(buf) - 1] = '\0';
name = new_id_from_str(buf);
spill_ent = new_entity(frame, name, get_spill_type(ssenv->types, ss[i]));