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

- Implement all the state switching stuff needed for efficient fpu mode

  switching in x87
- Only emit externally allocated symbols that are actually used

[r12625]
parent 8c11cfb8
......@@ -363,7 +363,7 @@ static void TEMPLATE_done(void *self) {
TEMPLATE_isa_t *isa = self;
/* emit now all global declarations */
be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env);
be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env, 0);
be_emit_destroy_env(&isa->emit);
free(self);
......
#ifndef __BE_DBGOUT_H__
#define __BE_DBGOUT_H__
/**
* Debug output support.
*
* @author Michael Beck
* @date 11.9.2006
* @cvsid $Id$
* @file
* @brief Debug output support.
* @author Michael Beck
* @date 11.9.2006
* @version $Id$
*/
#ifndef __BE_DBGOUT_H__
#define __BE_DBGOUT_H__
#include "obst.h"
#include "beabi_t.h"
......
......@@ -36,7 +36,7 @@
#include "belive_t.h"
#include "besched_t.h"
#include "beirg.h"
#include "beirgmod.h"
#include "bessaconstr.h"
typedef struct _be_abi_call_arg_t {
unsigned is_res : 1; /**< 1: the call argument is a return value. 0: it's a call parameter. */
......@@ -894,6 +894,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
ir_node *subsp, *mem, *res, *size, *sync;
ir_type *type;
ir_node *in[2];
ir_mode *sp_mode;
if (get_Free_where(free) != stack_alloc) {
assert(0);
......@@ -903,6 +904,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
block = get_nodes_block(free);
irg = get_irn_irg(block);
type = get_Free_type(free);
sp_mode = env->isa->sp->reg_class->mode;
/* we might need to multiply the size with the element size */
if(type != get_unknown_type() && get_type_size_bytes(type) != 1) {
......@@ -921,7 +923,7 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
subsp = be_new_SubSP(env->isa->sp, irg, block, curr_sp, size);
mem = new_r_Proj(irg, block, subsp, mode_M, pn_be_SubSP_M);
res = new_r_Proj(irg, block, subsp, mode_P_data, pn_be_SubSP_res);
res = new_r_Proj(irg, block, subsp, sp_mode, pn_be_SubSP_res);
/* we need to sync the memory */
in[0] = get_Free_mem(free);
......@@ -1672,7 +1674,9 @@ static void modify_irg(be_abi_irg_t *env)
ir_graph *irg = env->birg->irg;
ir_node *bl = get_irg_start_block(irg);
ir_node *end = get_irg_end_block(irg);
ir_node *mem = get_irg_initial_mem(irg);
ir_node *old_mem = get_irg_initial_mem(irg);
ir_node *new_mem_proj;
ir_node *mem;
ir_type *method_type = get_entity_type(get_irg_entity(irg));
pset *dont_save = pset_new_ptr(8);
......@@ -1813,6 +1817,13 @@ static void modify_irg(be_abi_irg_t *env)
}
obstack_free(&env->obst, rm);
/* create a new initial memory proj */
assert(is_Proj(old_mem));
new_mem_proj = new_r_Proj(irg, get_nodes_block(old_mem),
new_r_Unknown(irg, mode_T), mode_M,
get_Proj_proj(old_mem));
mem = new_mem_proj;
/* Generate the Prologue */
fp_reg = call->cb->prologue(env->cb, &mem, env->regs);
......@@ -1831,6 +1842,10 @@ static void modify_irg(be_abi_irg_t *env)
set_irg_frame(irg, frame_pointer);
pset_insert_ptr(env->ignore_regs, fp_reg);
/* rewire old mem users to new mem */
set_Proj_pred(new_mem_proj, get_Proj_pred(old_mem));
exchange(old_mem, mem);
set_irg_initial_mem(irg, mem);
/* Now, introduce stack param nodes for all parameters passed on the stack */
......@@ -2054,8 +2069,6 @@ typedef ir_node **node_array;
typedef struct fix_stack_walker_env_t {
node_array sp_nodes;
node_array *state_nodes;
const arch_register_t **state_regs;
const arch_env_t *arch_env;
} fix_stack_walker_env_t;
......@@ -2066,99 +2079,65 @@ static void collect_stack_nodes_walker(ir_node *node, void *data)
{
fix_stack_walker_env_t *env = data;
if (is_Block(node))
return;
if (arch_irn_is(env->arch_env, node, modify_sp)) {
assert(get_irn_mode(node) != mode_M && get_irn_mode(node) != mode_T);
ARR_APP1(ir_node*, env->sp_nodes, node);
}
if(ARR_LEN(env->state_nodes) > 0) {
int i, n;
const arch_register_t *reg = arch_get_irn_register(env->arch_env, node);
n = ARR_LEN(env->state_nodes);
for(i = 0; i < n; ++i) {
if(reg == env->state_regs[i]) {
ARR_APP1(ir_node*, env->state_nodes[i], node);
}
}
}
}
void be_abi_fix_stack_nodes(be_abi_irg_t *env)
{
int i, n;
be_ssa_construction_env_t senv;
int i, len;
ir_node **phis;
be_irg_t *birg = env->birg;
be_lv_t *lv = be_get_birg_liveness(birg);
fix_stack_walker_env_t walker_env;
arch_isa_t *isa;
walker_env.sp_nodes = NEW_ARR_F(ir_node*, 0);
walker_env.arch_env = birg->main_env->arch_env;
walker_env.state_nodes = NEW_ARR_F(node_array, 0);
walker_env.state_regs = NEW_ARR_F(const arch_register_t*, 0);
isa = walker_env.arch_env->isa;
/* collect all state registers */
for(i = 0, n = arch_isa_get_n_reg_class(isa); i < n; ++i) {
const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i);
int j, n_regs = cls->n_regs;
irg_walk_graph(birg->irg, collect_stack_nodes_walker, NULL, &walker_env);
for(j = 0; j < n_regs; ++j) {
const arch_register_t *reg = arch_register_for_index(cls, j);
if(arch_register_type_is(reg, state)) {
node_array arr = NEW_ARR_F(ir_node*, 0);
ARR_APP1(node_array, walker_env.state_nodes, arr);
ARR_APP1(const arch_register_t*, walker_env.state_regs, reg);
}
}
/* nothing to be done if we didn't find any node, in fact we mustn't
* continue, as for endless loops incsp might have had no users and is bad
* now.
*/
len = ARR_LEN(walker_env.sp_nodes);
if(len == 0) {
DEL_ARR_F(walker_env.sp_nodes);
return;
}
irg_walk_graph(birg->irg, collect_stack_nodes_walker, NULL, &walker_env);
be_ssa_construction_init(&senv, birg);
be_ssa_construction_add_copies(&senv, walker_env.sp_nodes,
ARR_LEN(walker_env.sp_nodes));
be_ssa_construction_fix_users_array(&senv, walker_env.sp_nodes,
ARR_LEN(walker_env.sp_nodes));
be_assure_dom_front(birg);
phis = be_ssa_construction(
be_get_birg_dom_front(birg),
be_get_birg_liveness(birg),
env->init_sp,
ARR_LEN(walker_env.sp_nodes), walker_env.sp_nodes,
NULL, 1);
if(lv != NULL) {
len = ARR_LEN(walker_env.sp_nodes);
for(i = 0; i < len; ++i) {
be_liveness_update(lv, walker_env.sp_nodes[i]);
}
be_ssa_construction_update_liveness_phis(&senv, lv);
}
phis = be_ssa_construction_get_new_phis(&senv);
/* set register requirements for stack phis */
for(i = 0; i < ARR_LEN(phis); ++i) {
len = ARR_LEN(phis);
for(i = 0; i < len; ++i) {
ir_node *phi = phis[i];
be_set_phi_reg_req(walker_env.arch_env, phi, &env->sp_req);
be_set_phi_flags(walker_env.arch_env, phi, arch_irn_flags_ignore | arch_irn_flags_modify_sp);
arch_set_irn_register(walker_env.arch_env, phi, env->isa->sp);
}
be_ssa_construction_destroy(&senv);
DEL_ARR_F(phis);
DEL_ARR_F(walker_env.sp_nodes);
n = ARR_LEN(walker_env.state_nodes);
for(i = 0; i < n; ++i) {
const arch_register_t *reg = walker_env.state_regs[i];
node_array nodes = walker_env.state_nodes[i];
ir_node *initial_value = be_abi_reg_map_get(env->regs, reg);
phis = be_ssa_construction(
be_get_birg_dom_front(birg),
be_get_birg_liveness(birg),
initial_value,
ARR_LEN(nodes), nodes,
NULL, 1);
/* set registers for the phis */
for(i = 0; i < ARR_LEN(phis); ++i) {
ir_node *phi = phis[i];
be_set_phi_flags(walker_env.arch_env, phi, arch_irn_flags_ignore);
arch_set_irn_register(walker_env.arch_env, phi, reg);
}
DEL_ARR_F(phis);
DEL_ARR_F(nodes);
}
}
static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
......
......@@ -55,8 +55,7 @@
#include "bechordal_t.h"
#include "bechordal_draw.h"
#define DBG_LEVEL SET_LEVEL_0
#define DBG_LEVEL_CHECK SET_LEVEL_0
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
#define NO_COLOR (-1)
......@@ -71,7 +70,6 @@ typedef struct _be_chordal_alloc_env_t {
bitset_t *colors; /**< The color mask. */
bitset_t *in_colors; /**< Colors used by live in values. */
int colors_n; /**< The number of colors. */
DEBUG_ONLY(firm_dbg_module_t *constr_dbg;) /**< Debug output for the constraint handler. */
} be_chordal_alloc_env_t;
#include "fourcc.h"
......@@ -414,7 +412,6 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env,
be_insn_t *insn = *the_insn;
ir_node *perm = NULL;
bitset_t *out_constr = bitset_alloca(env->cls->n_regs);
be_lv_t *lv = env->birg->lv;
const ir_edge_t *edge;
int i;
......@@ -436,7 +433,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env,
Make the Perm, recompute liveness and re-scan the insn since the
in operands are now the Projs of the Perm.
*/
perm = insert_Perm_after(aenv, lv, env->cls, env->birg->dom_front, sched_prev(insn->irn));
perm = insert_Perm_after(env->birg, env->cls, sched_prev(insn->irn));
/* Registers are propagated by insert_Perm_after(). Clean them here! */
if(perm == NULL)
......@@ -485,7 +482,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
hungarian_problem_t *bp;
int *assignment;
pmap *partners;
DEBUG_ONLY(firm_dbg_module_t *dbg);
int i, n_alloc;
long col;
const ir_edge_t *edge;
......@@ -532,7 +528,6 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
// bipartite_t *bp = bipartite_new(n_regs, n_regs);
assignment = alloca(n_regs * sizeof(assignment[0]));
partners = pmap_create();
DEBUG_ONLY(dbg = alloc_env->constr_dbg;)
/*
prepare the constraint handling of this node.
......@@ -725,7 +720,6 @@ static void pressure(ir_node *block, void *env_ptr)
bitset_t *live = alloc_env->live;
ir_node *irn;
be_lv_t *lv = env->birg->lv;
DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
int i, n;
unsigned step = 0;
......@@ -831,7 +825,6 @@ static void assign(ir_node *block, void *env_ptr)
const ir_node *irn;
border_t *b;
DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
bitset_clear_all(colors);
bitset_clear_all(live);
......@@ -914,7 +907,11 @@ static void assign(ir_node *block, void *env_ptr)
assert(reg && "Register must have been assigned");
col = arch_register_get_index(reg);
assert(bitset_is_set(live, nr) && "Cannot have a non live use");
#ifndef NDEBUG
if(!arch_register_type_is(reg, ignore)) {
assert(bitset_is_set(live, nr) && "Cannot have a non live use");
}
#endif
bitset_clear(colors, col);
bitset_clear(live, nr);
......@@ -929,10 +926,15 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
be_chordal_alloc_env_t env;
char buf[256];
be_irg_t *birg = chordal_env->birg;
const arch_register_class_t *cls = chordal_env->cls;
int colors_n = arch_register_class_n_regs(chordal_env->cls);
int colors_n = arch_register_class_n_regs(cls);
ir_graph *irg = chordal_env->irg;
int allocatable_regs = colors_n - be_put_ignore_regs(birg, cls, NULL);
/* some special classes contain only ignore regs, no work to be done */
if(allocatable_regs == 0)
return;
be_assure_dom_front(birg);
be_assure_liveness(birg);
......@@ -944,8 +946,6 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
env.tmp_colors = bitset_alloca(colors_n);
env.in_colors = bitset_alloca(colors_n);
env.pre_colored = pset_new_ptr_default();
FIRM_DBG_REGISTER(env.constr_dbg, "firm.be.chordal.constr");
/* Handle register targeting constraints */
dom_tree_walk_irg(irg, constraints, NULL, &env);
......@@ -974,3 +974,10 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
bitset_free(env.live);
del_pset(env.pre_colored);
}
void be_init_chordal(void)
{
FIRM_DBG_REGISTER(dbg, "firm.be.chordal.constr");
}
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_chordal);
......@@ -416,6 +416,12 @@ static void post_spill(post_spill_env_t *pse, int iteration) {
const be_main_env_t *main_env = birg->main_env;
be_options_t *main_opts = main_env->options;
node_stat_t node_stat;
int colors_n = arch_register_class_n_regs(chordal_env->cls);
int allocatable_regs = colors_n - be_put_ignore_regs(birg, chordal_env->cls, NULL);
/* some special classes contain only ignore regs, no work to be done */
if(allocatable_regs == 0)
return;
#ifdef FIRM_STATISTICS
if (be_stat_ev_is_active()) {
......@@ -448,11 +454,11 @@ static void post_spill(post_spill_env_t *pse, int iteration) {
/* verify schedule and register pressure */
if (chordal_env->opts->vrfy_option == BE_CH_VRFY_WARN) {
be_verify_schedule(irg);
be_verify_schedule(birg);
be_verify_register_pressure(birg, pse->cls, irg);
}
else if (chordal_env->opts->vrfy_option == BE_CH_VRFY_ASSERT) {
assert(be_verify_schedule(irg) && "Schedule verification failed");
assert(be_verify_schedule(birg) && "Schedule verification failed");
assert(be_verify_register_pressure(birg, pse->cls, irg)
&& "Register pressure verification failed");
}
......@@ -617,7 +623,7 @@ static be_ra_t be_ra_chordal_allocator = {
be_ra_chordal_main,
};
void be_init_chordal(void)
void be_init_chordal_main(void)
{
lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
......@@ -628,4 +634,4 @@ void be_init_chordal(void)
be_register_allocator("chordal", &be_ra_chordal_allocator);
}
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_chordal);
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_chordal_main);
......@@ -464,7 +464,8 @@ static void co_collect_units(ir_node *irn, void *env) {
/* Src == Tgt of a 2-addr-code instruction */
if (is_2addr_code(req)) {
ir_node *other = get_irn_n(irn, req->other_same);
if (!nodes_interfere(co->cenv, irn, other)) {
if (!arch_irn_is(co->aenv, other, ignore) &&
!nodes_interfere(co->cenv, irn, other)) {
unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
unit->costs = xmalloc(2 * sizeof(*unit->costs));
unit->node_count = 2;
......@@ -784,7 +785,8 @@ static void build_graph_walker(ir_node *irn, void *env) {
arch_get_register_req(co->aenv, irn, -1);
if (is_2addr_code(req)) {
ir_node *other = get_irn_n(irn, req->other_same);
add_edges(co, irn, other, co->get_costs(co, irn, other, 0));
if(!arch_irn_is(co->aenv, other, ignore))
add_edges(co, irn, other, co->get_costs(co, irn, other, 0));
}
}
}
......
......@@ -20,6 +20,7 @@
#include "irnode.h"
#include "entity.h"
#include "irprog.h"
#include "pdeq.h"
#include "error.h"
#include "be_t.h"
......@@ -69,6 +70,7 @@ typedef struct _ia32_decl_env {
obstack_t *bss_obst;
obstack_t *ctor_obst;
const be_main_env_t *main_env;
waitq *worklist;
} ia32_decl_env_t;
/************************************************************************/
......@@ -171,20 +173,22 @@ static tarval *get_atomic_init_tv(ir_node *init)
/**
* dump an atomic value
*/
static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
static void do_dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
ir_node *init)
{
ir_mode *mode = get_irn_mode(init);
int bytes = get_mode_size_bytes(mode);
tarval *tv;
ir_entity *ent;
switch (get_irn_opcode(init)) {
case iro_Cast:
do_dump_atomic_init(obst, get_Cast_op(init));
do_dump_atomic_init(env, obst, get_Cast_op(init));
return;
case iro_Conv:
do_dump_atomic_init(obst, get_Conv_op(init));
do_dump_atomic_init(env, obst, get_Conv_op(init));
return;
case iro_Const:
......@@ -201,11 +205,23 @@ static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
break;
case symconst_addr_ent:
obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
ent = get_SymConst_entity(init);
if(!entity_visited(ent)) {
waitq_put(env->worklist, ent);
mark_entity_visited(ent);
}
obstack_printf(obst, "%s", get_entity_ld_name(ent));
break;
case symconst_ofs_ent:
obstack_printf(obst, "%d", get_entity_offset(get_SymConst_entity(init)));
ent = get_SymConst_entity(init);
#if 0 /* not needed, is it? */
if(!entity_visited(ent)) {
waitq_put(env->worklist, ent);
mark_entity_visited(ent);
}
#endif
obstack_printf(obst, "%d", get_entity_offset(ent));
break;
case symconst_type_size:
......@@ -227,21 +243,21 @@ static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
return;
case iro_Add:
do_dump_atomic_init(obst, get_Add_left(init));
do_dump_atomic_init(env, obst, get_Add_left(init));
obstack_printf(obst, " + ");
do_dump_atomic_init(obst, get_Add_right(init));
do_dump_atomic_init(env, obst, get_Add_right(init));
return;
case iro_Sub:
do_dump_atomic_init(obst, get_Sub_left(init));
do_dump_atomic_init(env, obst, get_Sub_left(init));
obstack_printf(obst, " - ");
do_dump_atomic_init(obst, get_Sub_right(init));
do_dump_atomic_init(env, obst, get_Sub_right(init));
return;
case iro_Mul:
do_dump_atomic_init(obst, get_Mul_left(init));
do_dump_atomic_init(env, obst, get_Mul_left(init));
obstack_printf(obst, " * ");
do_dump_atomic_init(obst, get_Mul_right(init));
do_dump_atomic_init(env, obst, get_Mul_right(init));
return;
default:
......@@ -289,13 +305,14 @@ static void dump_size_type(obstack_t *obst, int size) {
/**
* dump an atomic value to an obstack
*/
static void dump_atomic_init(obstack_t *obst, ir_node *init)
static void dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
ir_node *init)
{
ir_mode *mode = get_irn_mode(init);
int bytes = get_mode_size_bytes(mode);
dump_size_type(obst, bytes);
do_dump_atomic_init(obst, init);
do_dump_atomic_init(env, obst, init);
obstack_printf(obst, "\n");
}
......@@ -388,7 +405,8 @@ static void dump_string_cst(obstack_t *obst, ir_entity *ent)
obstack_printf(obst, "\"\n");
}
static void dump_array_init(obstack_t *obst, ir_entity *ent)
static void dump_array_init(ia32_decl_env_t *env, obstack_t *obst,
ir_entity *ent)
{
const ir_type *ty = get_entity_type(ent);
int i;
......@@ -409,7 +427,7 @@ static void dump_array_init(obstack_t *obst, ir_entity *ent)
size += align - n;
}
}
dump_atomic_init(obst, get_compound_ent_value(ent, i));
dump_atomic_init(env, obst, get_compound_ent_value(ent, i));
size += get_type_size_bytes(stype);
}
filler = get_type_size_bytes(ty) - size;
......@@ -434,7 +452,8 @@ typedef struct {
/**
* Dump an initializer for a compound entity.
*/
static void dump_compound_init(obstack_t *obst, ir_entity *ent)
static void dump_compound_init(ia32_decl_env_t *env, obstack_t *obst,
ir_entity *ent)
{
normal_or_bitfield *vals;
int i, j, n = get_compound_ent_n_values(ent);
......@@ -443,7 +462,7 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
/* Find the initializer size. Sorrily gcc support a nasty feature:
The last field of a compound may be a flexible array. This allows
initializers bigger than the type size. */
last_ofs = 0;
last_ofs = get_type_size_bytes(get_entity_type(ent));
for (i = 0; i < n; ++i) {
int offset = get_compound_ent_value_offset_bytes(ent, i);
int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
......@@ -514,7 +533,7 @@ static void dump_compound_init(obstack_t *obst, ir_entity *ent)
int space = 0, skip = 0;
if (vals[i].kind == NORMAL) {
if(vals[i].v.value != NULL) {
dump_atomic_init(obst, vals[i].v.value);
dump_atomic_init(env, obst, vals[i].v.value);
skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
} else {
space = 1;
......@@ -599,13 +618,13 @@ static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
}
} else if (is_atomic_type(type)) {
dump_atomic_init(obst, get_atomic_ent_value(ent));
dump_atomic_init(env, obst, get_atomic_ent_value(ent));
} else if (ent_is_string_const(ent)) {
dump_string_cst(obst, ent);
} else if (is_Array_type(type)) {
dump_array_init(obst, ent);
dump_array_init(env, obst, ent);
} else if (is_compound_type(type)) {
dump_compound_init(obst, ent);
dump_compound_init(env, obst, ent);
} else {
assert(0 && "unsupported type");
}
......@@ -614,19 +633,47 @@ static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
/**
* Dumps declarations of global variables and the initialization code.
*/
static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env, int emit_commons)
static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env,
int emit_commons, int only_emit_marked)
{
int i, n = get_compound_n_members(gt);
waitq *worklist = new_waitq();
if(only_emit_marked) {
for (i = 0; i < n; i++) {
ir_entity *ent = get_compound_member(gt, i);
if(entity_visited(ent) ||
get_entity_visibility(ent) != visibility_external_allocated) {
waitq_put(worklist, ent);
mark_entity_visited(ent);
}
}
} else {
inc_master_type_visited();
for (i = 0; i < n; i++) {
ir_entity *ent = get_compound_member(gt, i);
mark_entity_visited(ent);
waitq_put(worklist, ent);
}
}
env->worklist = worklist;
while(!waitq_empty(worklist)) {
ir_entity *ent = waitq_get(worklist);
for (i = 0; i < n; i++) {
ir_entity *ent = get_compound_member(gt, i);
dump_global(env, ent, emit_commons);
}