- Implement goto support
- Register allocator bug fixes. * coalesce_live_ranges now also updates the interference graph of live instructions * resolve_tangle now avoids copies to phi * correct_tangles is now called in a loop so that all tangles get fixed - Bug the version of romcc to 0.30 git-svn-id: svn://svn.coreboot.org/coreboot/trunk@886 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
f7a0ba84dc
commit
153ea3548f
|
@ -1,5 +1,5 @@
|
||||||
VERSION:=0.29
|
VERSION:=0.30
|
||||||
RELEASE_DATE:=19 June 2003
|
RELEASE_DATE:=20 June 2003
|
||||||
PACKAGE:=romcc
|
PACKAGE:=romcc
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ TESTS=\
|
||||||
simple_test35.c \
|
simple_test35.c \
|
||||||
simple_test36.c \
|
simple_test36.c \
|
||||||
simple_test37.c \
|
simple_test37.c \
|
||||||
|
simple_test38.c \
|
||||||
raminit_test.c \
|
raminit_test.c \
|
||||||
raminit_test2.c \
|
raminit_test2.c \
|
||||||
raminit_test3.c \
|
raminit_test3.c \
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#define DEBUG_ERROR_MESSAGES 0
|
#define DEBUG_ERROR_MESSAGES 0
|
||||||
#define DEBUG_COLOR_GRAPH 0
|
#define DEBUG_COLOR_GRAPH 0
|
||||||
#define DEBUG_SCC 0
|
#define DEBUG_SCC 0
|
||||||
#define DEBUG_CONSISTENCY 1
|
#define DEBUG_CONSISTENCY 2
|
||||||
|
|
||||||
#warning "FIXME boundary cases with small types in larger registers"
|
#warning "FIXME boundary cases with small types in larger registers"
|
||||||
#warning "FIXME give clear error messages about unused variables"
|
#warning "FIXME give clear error messages about unused variables"
|
||||||
|
@ -858,11 +858,7 @@ struct type {
|
||||||
|
|
||||||
#define MAX_REGISTERS 75
|
#define MAX_REGISTERS 75
|
||||||
#define MAX_REG_EQUIVS 16
|
#define MAX_REG_EQUIVS 16
|
||||||
#if 1
|
|
||||||
#define REGISTER_BITS 16
|
#define REGISTER_BITS 16
|
||||||
#else
|
|
||||||
#define REGISTER_BITS 28
|
|
||||||
#endif
|
|
||||||
#define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
|
#define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
|
||||||
#define TEMPLATE_BITS 6
|
#define TEMPLATE_BITS 6
|
||||||
#define MAX_TEMPLATES (1<<TEMPLATE_BITS)
|
#define MAX_TEMPLATES (1<<TEMPLATE_BITS)
|
||||||
|
@ -881,7 +877,6 @@ struct type {
|
||||||
#define REG_VIRT9 (MAX_REGISTERS + 5)
|
#define REG_VIRT9 (MAX_REGISTERS + 5)
|
||||||
|
|
||||||
/* Provision for 8 register classes */
|
/* Provision for 8 register classes */
|
||||||
#if 1
|
|
||||||
#define REG_SHIFT 0
|
#define REG_SHIFT 0
|
||||||
#define REGC_SHIFT REGISTER_BITS
|
#define REGC_SHIFT REGISTER_BITS
|
||||||
#define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
|
#define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
|
||||||
|
@ -892,11 +887,6 @@ struct type {
|
||||||
#define SET_REGCM(ID, REGCM) ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
|
#define SET_REGCM(ID, REGCM) ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
|
||||||
#define SET_INFO(ID, INFO) ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
|
#define SET_INFO(ID, INFO) ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
|
||||||
(((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
|
(((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
|
||||||
#else
|
|
||||||
#define REG_MASK (MAX_VIRT_REGISTERS -1)
|
|
||||||
#define ID_REG(ID) ((ID) & REG_MASK)
|
|
||||||
#define SET_REG(ID, REG) ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned arch_reg_regcm(struct compile_state *state, int reg);
|
static unsigned arch_reg_regcm(struct compile_state *state, int reg);
|
||||||
static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
|
static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
|
||||||
|
@ -934,6 +924,7 @@ static struct triple *transform_to_arch_instruction(
|
||||||
#define DEBUG_INSERTED_COPIES 0x0400
|
#define DEBUG_INSERTED_COPIES 0x0400
|
||||||
|
|
||||||
#define GLOBAL_SCOPE_DEPTH 1
|
#define GLOBAL_SCOPE_DEPTH 1
|
||||||
|
#define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
|
||||||
|
|
||||||
static void compile_file(struct compile_state *old_state, const char *filename, int local);
|
static void compile_file(struct compile_state *old_state, const char *filename, int local);
|
||||||
|
|
||||||
|
@ -2169,6 +2160,22 @@ static void symbol(
|
||||||
*chain = sym;
|
*chain = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void label_symbol(struct compile_state *state,
|
||||||
|
struct hash_entry *ident, struct triple *label)
|
||||||
|
{
|
||||||
|
struct symbol *sym;
|
||||||
|
if (ident->sym_label) {
|
||||||
|
error(state, 0, "label %s already defined", ident->name);
|
||||||
|
}
|
||||||
|
sym = xcmalloc(sizeof(*sym), "label");
|
||||||
|
sym->ident = ident;
|
||||||
|
sym->def = label;
|
||||||
|
sym->type = &void_type;
|
||||||
|
sym->scope_depth = FUNCTION_SCOPE_DEPTH;
|
||||||
|
sym->next = 0;
|
||||||
|
ident->sym_label = sym;
|
||||||
|
}
|
||||||
|
|
||||||
static void start_scope(struct compile_state *state)
|
static void start_scope(struct compile_state *state)
|
||||||
{
|
{
|
||||||
state->scope_depth++;
|
state->scope_depth++;
|
||||||
|
@ -7793,22 +7800,46 @@ static void continue_statement(struct compile_state *state, struct triple *first
|
||||||
|
|
||||||
static void goto_statement(struct compile_state *state, struct triple *first)
|
static void goto_statement(struct compile_state *state, struct triple *first)
|
||||||
{
|
{
|
||||||
FINISHME();
|
struct hash_entry *ident;
|
||||||
eat(state, TOK_GOTO);
|
eat(state, TOK_GOTO);
|
||||||
eat(state, TOK_IDENT);
|
eat(state, TOK_IDENT);
|
||||||
|
ident = state->token[0].ident;
|
||||||
|
if (!ident->sym_label) {
|
||||||
|
/* If this is a forward branch allocate the label now,
|
||||||
|
* it will be flattend in the appropriate location later.
|
||||||
|
*/
|
||||||
|
struct triple *ins;
|
||||||
|
ins = label(state);
|
||||||
|
label_symbol(state, ident, ins);
|
||||||
|
}
|
||||||
eat(state, TOK_SEMI);
|
eat(state, TOK_SEMI);
|
||||||
error(state, 0, "goto is not implemeted");
|
|
||||||
FINISHME();
|
flatten(state, first, branch(state, ident->sym_label->def, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void labeled_statement(struct compile_state *state, struct triple *first)
|
static void labeled_statement(struct compile_state *state, struct triple *first)
|
||||||
{
|
{
|
||||||
FINISHME();
|
struct triple *ins;
|
||||||
|
struct hash_entry *ident;
|
||||||
eat(state, TOK_IDENT);
|
eat(state, TOK_IDENT);
|
||||||
|
|
||||||
|
ident = state->token[0].ident;
|
||||||
|
if (ident->sym_label && ident->sym_label->def) {
|
||||||
|
ins = ident->sym_label->def;
|
||||||
|
put_occurance(ins->occurance);
|
||||||
|
ins->occurance = new_occurance(state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ins = label(state);
|
||||||
|
label_symbol(state, ident, ins);
|
||||||
|
}
|
||||||
|
if (ins->id & TRIPLE_FLAG_FLATTENED) {
|
||||||
|
error(state, 0, "label %s already defined", ident->name);
|
||||||
|
}
|
||||||
|
flatten(state, first, ins);
|
||||||
|
|
||||||
eat(state, TOK_COLON);
|
eat(state, TOK_COLON);
|
||||||
statement(state, first);
|
statement(state, first);
|
||||||
error(state, 0, "labeled statements are not implemented");
|
|
||||||
FINISHME();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switch_statement(struct compile_state *state, struct triple *first)
|
static void switch_statement(struct compile_state *state, struct triple *first)
|
||||||
|
@ -8845,6 +8876,30 @@ static struct triple *initializer(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void resolve_branches(struct compile_state *state)
|
||||||
|
{
|
||||||
|
/* Make a second pass and finish anything outstanding
|
||||||
|
* with respect to branches. The only outstanding item
|
||||||
|
* is to see if there are goto to labels that have not
|
||||||
|
* been defined and to error about them.
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < HASH_TABLE_SIZE; i++) {
|
||||||
|
struct hash_entry *entry;
|
||||||
|
for(entry = state->hash_table[i]; entry; entry = entry->next) {
|
||||||
|
struct triple *ins;
|
||||||
|
if (!entry->sym_label) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ins = entry->sym_label->def;
|
||||||
|
if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
|
||||||
|
error(state, ins, "label `%s' used but not defined",
|
||||||
|
entry->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct triple *function_definition(
|
static struct triple *function_definition(
|
||||||
struct compile_state *state, struct type *type)
|
struct compile_state *state, struct type *type)
|
||||||
{
|
{
|
||||||
|
@ -8926,8 +8981,12 @@ static struct triple *function_definition(
|
||||||
/* Now get the actual function definition */
|
/* Now get the actual function definition */
|
||||||
compound_statement(state, end);
|
compound_statement(state, end);
|
||||||
|
|
||||||
|
/* Finish anything unfinished with branches */
|
||||||
|
resolve_branches(state);
|
||||||
|
|
||||||
/* Remove the parameter scope */
|
/* Remove the parameter scope */
|
||||||
end_scope(state);
|
end_scope(state);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
loc(stdout, state, 0);
|
loc(stdout, state, 0);
|
||||||
|
@ -10781,6 +10840,9 @@ static struct triple *pre_copy(
|
||||||
*/
|
*/
|
||||||
struct triple *in;
|
struct triple *in;
|
||||||
struct triple **expr;
|
struct triple **expr;
|
||||||
|
if (ins->op == OP_PHI) {
|
||||||
|
internal_error(state, ins, "pre_copy on a phi?");
|
||||||
|
}
|
||||||
expr = &RHS(ins, index);
|
expr = &RHS(ins, index);
|
||||||
in = pre_triple(state, ins, OP_COPY, (*expr)->type, *expr, 0);
|
in = pre_triple(state, ins, OP_COPY, (*expr)->type, *expr, 0);
|
||||||
unuse_triple(*expr, ins);
|
unuse_triple(*expr, ins);
|
||||||
|
@ -11772,6 +11834,19 @@ static void remove_live_edges(struct reg_state *rstate, struct live_range *range
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void transfer_live_edges(struct reg_state *rstate,
|
||||||
|
struct live_range *dest, struct live_range *src)
|
||||||
|
{
|
||||||
|
struct live_range_edge *edge, *next;
|
||||||
|
for(edge = src->edges; edge; edge = next) {
|
||||||
|
struct live_range *other;
|
||||||
|
next = edge->next;
|
||||||
|
other = edge->node;
|
||||||
|
remove_live_edge(rstate, src, other);
|
||||||
|
add_live_edge(rstate, dest, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Interference graph...
|
/* Interference graph...
|
||||||
*
|
*
|
||||||
|
@ -11887,7 +11962,7 @@ static struct live_range *coalesce_ranges(
|
||||||
fprintf(stderr, "lr2 pre\n");
|
fprintf(stderr, "lr2 pre\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 0
|
||||||
fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
|
fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
|
||||||
lr1->defs->def,
|
lr1->defs->def,
|
||||||
lr1->color,
|
lr1->color,
|
||||||
|
@ -11898,6 +11973,12 @@ static struct live_range *coalesce_ranges(
|
||||||
lr1->classes = classes;
|
lr1->classes = classes;
|
||||||
/* Append lr2 onto lr1 */
|
/* Append lr2 onto lr1 */
|
||||||
#warning "FIXME should this be a merge instead of a splice?"
|
#warning "FIXME should this be a merge instead of a splice?"
|
||||||
|
/* This FIXME item applies to the correctness of live_range_end
|
||||||
|
* and to the necessity of making multiple passes of coalesce_live_ranges.
|
||||||
|
* A failure to find some coalesce opportunities in coaleace_live_ranges
|
||||||
|
* does not impact the correct of the compiler just the efficiency with
|
||||||
|
* which registers are allocated.
|
||||||
|
*/
|
||||||
head = lr1->defs;
|
head = lr1->defs;
|
||||||
mid1 = lr1->defs->prev;
|
mid1 = lr1->defs->prev;
|
||||||
mid2 = lr2->defs;
|
mid2 = lr2->defs;
|
||||||
|
@ -11928,6 +12009,9 @@ static struct live_range *coalesce_ranges(
|
||||||
lr1->color = color;
|
lr1->color = color;
|
||||||
lr1->classes = classes;
|
lr1->classes = classes;
|
||||||
|
|
||||||
|
/* Keep the graph in sync by transfering the edges from lr2 to lr1 */
|
||||||
|
transfer_live_edges(rstate, lr1, lr2);
|
||||||
|
|
||||||
return lr1;
|
return lr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12505,6 +12589,7 @@ static void fix_tangles(struct compile_state *state,
|
||||||
struct reg_block *blocks, struct triple_reg_set *live,
|
struct reg_block *blocks, struct triple_reg_set *live,
|
||||||
struct reg_block *rb, struct triple *ins, void *arg)
|
struct reg_block *rb, struct triple *ins, void *arg)
|
||||||
{
|
{
|
||||||
|
int *tangles = arg;
|
||||||
struct triple *tangle;
|
struct triple *tangle;
|
||||||
do {
|
do {
|
||||||
char used[MAX_REGISTERS];
|
char used[MAX_REGISTERS];
|
||||||
|
@ -12531,6 +12616,13 @@ static void fix_tangles(struct compile_state *state,
|
||||||
if (used[info.reg] < 2) {
|
if (used[info.reg] < 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* Changing copies that feed into phi functions
|
||||||
|
* is incorrect.
|
||||||
|
*/
|
||||||
|
if (set->member->use &&
|
||||||
|
(set->member->use->member->op == OP_PHI)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!tangle || tdominates(state, set->member, tangle)) {
|
if (!tangle || tdominates(state, set->member, tangle)) {
|
||||||
tangle = set->member;
|
tangle = set->member;
|
||||||
}
|
}
|
||||||
|
@ -12538,6 +12630,7 @@ static void fix_tangles(struct compile_state *state,
|
||||||
/* If I have found a tangle resolve it */
|
/* If I have found a tangle resolve it */
|
||||||
if (tangle) {
|
if (tangle) {
|
||||||
struct triple *post_copy;
|
struct triple *post_copy;
|
||||||
|
(*tangles)++;
|
||||||
post_copy = resolve_tangle(state, tangle);
|
post_copy = resolve_tangle(state, tangle);
|
||||||
if (post_copy) {
|
if (post_copy) {
|
||||||
replace_block_use(state, blocks, tangle, post_copy);
|
replace_block_use(state, blocks, tangle, post_copy);
|
||||||
|
@ -12550,11 +12643,14 @@ static void fix_tangles(struct compile_state *state,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void correct_tangles(
|
static int correct_tangles(
|
||||||
struct compile_state *state, struct reg_block *blocks)
|
struct compile_state *state, struct reg_block *blocks)
|
||||||
{
|
{
|
||||||
|
int tangles;
|
||||||
|
tangles = 0;
|
||||||
color_instructions(state);
|
color_instructions(state);
|
||||||
walk_variable_lifetimes(state, blocks, fix_tangles, 0);
|
walk_variable_lifetimes(state, blocks, fix_tangles, &tangles);
|
||||||
|
return tangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct least_conflict {
|
struct least_conflict {
|
||||||
|
@ -13536,6 +13632,7 @@ static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate
|
||||||
rstate->blocks = 0;
|
rstate->blocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void verify_consistency(struct compile_state *state);
|
||||||
static void allocate_registers(struct compile_state *state)
|
static void allocate_registers(struct compile_state *state)
|
||||||
{
|
{
|
||||||
struct reg_state rstate;
|
struct reg_state rstate;
|
||||||
|
@ -13547,8 +13644,13 @@ static void allocate_registers(struct compile_state *state)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
struct live_range **point, **next;
|
struct live_range **point, **next;
|
||||||
|
int tangles;
|
||||||
int coalesced;
|
int coalesced;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "pass: %d\n", rstate.passes);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Restore ids */
|
/* Restore ids */
|
||||||
ids_from_rstate(state, &rstate);
|
ids_from_rstate(state, &rstate);
|
||||||
|
|
||||||
|
@ -13562,26 +13664,38 @@ static void allocate_registers(struct compile_state *state)
|
||||||
walk_variable_lifetimes(
|
walk_variable_lifetimes(
|
||||||
state, rstate.blocks, fix_coalesce_conflicts, 0);
|
state, rstate.blocks, fix_coalesce_conflicts, 0);
|
||||||
|
|
||||||
/* Fix two simultaneous uses of the same register */
|
/* Fix two simultaneous uses of the same register.
|
||||||
correct_tangles(state, rstate.blocks);
|
* In a few pathlogical cases a partial untangle moves
|
||||||
|
* the tangle to a part of the graph we won't revisit.
|
||||||
|
* So we keep looping until we have no more tangle fixes
|
||||||
|
* to apply.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
tangles = correct_tangles(state, rstate.blocks);
|
||||||
|
} while(tangles);
|
||||||
|
|
||||||
if (state->debug & DEBUG_INSERTED_COPIES) {
|
if (state->debug & DEBUG_INSERTED_COPIES) {
|
||||||
printf("After resolve_tangles\n");
|
printf("After resolve_tangles\n");
|
||||||
print_blocks(state, stdout);
|
print_blocks(state, stdout);
|
||||||
print_control_flow(state);
|
print_control_flow(state);
|
||||||
}
|
}
|
||||||
|
verify_consistency(state);
|
||||||
|
|
||||||
/* Allocate and initialize the live ranges */
|
/* Allocate and initialize the live ranges */
|
||||||
initialize_live_ranges(state, &rstate);
|
initialize_live_ranges(state, &rstate);
|
||||||
|
|
||||||
|
/* Note current doing coalescing in a loop appears to
|
||||||
|
* buys me nothing. The code is left this way in case
|
||||||
|
* there is some value in it. Or if a future bugfix
|
||||||
|
* yields some benefit.
|
||||||
|
*/
|
||||||
do {
|
do {
|
||||||
/* Forget previous live range edge calculations */
|
|
||||||
cleanup_live_edges(&rstate);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "coalescing\n");
|
fprintf(stderr, "coalescing\n");
|
||||||
#endif
|
#endif
|
||||||
|
/* Remove any previous live edge calculations */
|
||||||
|
cleanup_live_edges(&rstate);
|
||||||
|
|
||||||
/* Compute the interference graph */
|
/* Compute the interference graph */
|
||||||
walk_variable_lifetimes(
|
walk_variable_lifetimes(
|
||||||
state, rstate.blocks, graph_ins, &rstate);
|
state, rstate.blocks, graph_ins, &rstate);
|
||||||
|
@ -13595,14 +13709,25 @@ static void allocate_registers(struct compile_state *state)
|
||||||
state, rstate.blocks,
|
state, rstate.blocks,
|
||||||
print_interference_ins, &rstate);
|
print_interference_ins, &rstate);
|
||||||
}
|
}
|
||||||
#if DEBUG_CONSISTENCY
|
|
||||||
|
coalesced = coalesce_live_ranges(state, &rstate);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr, "coalesced: %d\n", coalesced);
|
||||||
|
#endif
|
||||||
|
} while(coalesced);
|
||||||
|
|
||||||
|
#if DEBUG_CONSISTENCY > 1
|
||||||
|
# if 0
|
||||||
|
fprintf(stderr, "verify_graph_ins...\n");
|
||||||
|
# endif
|
||||||
/* Verify the interference graph */
|
/* Verify the interference graph */
|
||||||
walk_variable_lifetimes(
|
walk_variable_lifetimes(
|
||||||
state, rstate.blocks, verify_graph_ins, &rstate);
|
state, rstate.blocks, verify_graph_ins, &rstate);
|
||||||
|
# if 0
|
||||||
|
fprintf(stderr, "verify_graph_ins done\n");
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
coalesced = coalesce_live_ranges(state, &rstate);
|
|
||||||
} while(coalesced);
|
|
||||||
|
|
||||||
/* Build the groups low and high. But with the nodes
|
/* Build the groups low and high. But with the nodes
|
||||||
* first sorted by degree order.
|
* first sorted by degree order.
|
||||||
|
@ -14545,7 +14670,7 @@ static void verify_consistency(struct compile_state *state)
|
||||||
verify_ins_colors(state);
|
verify_ins_colors(state);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define verify_consistency(state) do {} while(0)
|
static void verify_consistency(struct compile_state *state) {}
|
||||||
#endif /* DEBUG_USES */
|
#endif /* DEBUG_USES */
|
||||||
|
|
||||||
static void optimize(struct compile_state *state)
|
static void optimize(struct compile_state *state)
|
||||||
|
|
Loading…
Reference in New Issue