1 /*
2 * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1223 switch (op->code()) {
1224 case lir_move: // fall through
1225 case lir_convert: {
1226 assert(op->as_Op1() != NULL, "lir_move, lir_convert must be LIR_Op1");
1227 LIR_Op1* move = (LIR_Op1*)op;
1228
1229 LIR_Opr move_from = move->in_opr();
1230 LIR_Opr move_to = move->result_opr();
1231
1232 if (move_to->is_register() && move_from->is_register()) {
1233 Interval* from = interval_at(reg_num(move_from));
1234 Interval* to = interval_at(reg_num(move_to));
1235 if (from != NULL && to != NULL) {
1236 to->set_register_hint(from);
1237 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", move->id(), from->reg_num(), to->reg_num()));
1238 }
1239 }
1240 break;
1241 }
1242 case lir_cmove: {
1243 assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2");
1244 LIR_Op2* cmove = (LIR_Op2*)op;
1245
1246 LIR_Opr move_from = cmove->in_opr1();
1247 LIR_Opr move_to = cmove->result_opr();
1248
1249 if (move_to->is_register() && move_from->is_register()) {
1250 Interval* from = interval_at(reg_num(move_from));
1251 Interval* to = interval_at(reg_num(move_to));
1252 if (from != NULL && to != NULL) {
1253 to->set_register_hint(from);
1254 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", cmove->id(), from->reg_num(), to->reg_num()));
1255 }
1256 }
1257 break;
1258 }
1259 default:
1260 break;
1261 }
1262 }
1263
1264
3121
3122 sort_intervals_after_allocation();
3123
3124 DEBUG_ONLY(verify());
3125
3126 eliminate_spill_moves();
3127 assign_reg_num();
3128 CHECK_BAILOUT();
3129
3130 NOT_PRODUCT(print_lir(2, "LIR after assignment of register numbers:"));
3131 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_after_asign));
3132
3133 { TIME_LINEAR_SCAN(timer_allocate_fpu_stack);
3134
3135 if (use_fpu_stack_allocation()) {
3136 allocate_fpu_stack(); // Only has effect on Intel
3137 NOT_PRODUCT(print_lir(2, "LIR after FPU stack allocation:"));
3138 }
3139 }
3140
3141 { TIME_LINEAR_SCAN(timer_optimize_lir);
3142
3143 EdgeMoveOptimizer::optimize(ir()->code());
3144 ControlFlowOptimizer::optimize(ir()->code());
3145 // check that cfg is still correct after optimizations
3146 ir()->verify();
3147 }
3148
3149 NOT_PRODUCT(print_lir(1, "Before Code Generation", false));
3150 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_final));
3151 NOT_PRODUCT(_total_timer.end_method(this));
3152 }
3153
3154
3155 // ********** Printing functions
3156
3157 #ifndef PRODUCT
3158
3159 void LinearScan::print_timers(double total) {
3160 _total_timer.print(total);
3161 }
3162
3163 void LinearScan::print_statistics() {
3164 _stat_before_alloc.print("before allocation");
3165 _stat_after_asign.print("after assignment of register");
3166 _stat_final.print("after optimization");
3167 }
6351 if (last_branch->info() == NULL) {
6352 if (last_branch->block() == code->at(i + 1)) {
6353
6354 TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id()));
6355
6356 // delete last branch instruction
6357 instructions->trunc_to(instructions->length() - 1);
6358
6359 } else {
6360 LIR_Op* prev_op = instructions->at(instructions->length() - 2);
6361 if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) {
6362 assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6363 LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
6364
6365 if (prev_branch->stub() == NULL) {
6366
6367 LIR_Op2* prev_cmp = NULL;
6368 // There might be a cmove inserted for profiling which depends on the same
6369 // compare. If we change the condition of the respective compare, we have
6370 // to take care of this cmove as well.
6371 LIR_Op2* prev_cmove = NULL;
6372
6373 for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
6374 prev_op = instructions->at(j);
6375 // check for the cmove
6376 if (prev_op->code() == lir_cmove) {
6377 assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2");
6378 prev_cmove = (LIR_Op2*)prev_op;
6379 assert(prev_branch->cond() == prev_cmove->condition(), "should be the same");
6380 }
6381 if (prev_op->code() == lir_cmp) {
6382 assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
6383 prev_cmp = (LIR_Op2*)prev_op;
6384 assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
6385 }
6386 }
6387 // Guarantee because it is dereferenced below.
6388 guarantee(prev_cmp != NULL, "should have found comp instruction for branch");
6389 if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
6390
6391 TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
6392
6393 // eliminate a conditional branch to the immediate successor
6394 prev_branch->change_block(last_branch->block());
6395 prev_branch->negate_cond();
6396 prev_cmp->set_condition(prev_branch->cond());
6397 instructions->trunc_to(instructions->length() - 1);
6398 // if we do change the condition, we have to change the cmove as well
|
1 /*
2 * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1223 switch (op->code()) {
1224 case lir_move: // fall through
1225 case lir_convert: {
1226 assert(op->as_Op1() != NULL, "lir_move, lir_convert must be LIR_Op1");
1227 LIR_Op1* move = (LIR_Op1*)op;
1228
1229 LIR_Opr move_from = move->in_opr();
1230 LIR_Opr move_to = move->result_opr();
1231
1232 if (move_to->is_register() && move_from->is_register()) {
1233 Interval* from = interval_at(reg_num(move_from));
1234 Interval* to = interval_at(reg_num(move_to));
1235 if (from != NULL && to != NULL) {
1236 to->set_register_hint(from);
1237 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", move->id(), from->reg_num(), to->reg_num()));
1238 }
1239 }
1240 break;
1241 }
1242 case lir_cmove: {
1243 #ifdef RISCV
1244 assert(op->as_Op4() != NULL, "lir_cmove must be LIR_Op4");
1245 LIR_Op4* cmove = (LIR_Op4*)op;
1246 #else
1247 assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2");
1248 LIR_Op2* cmove = (LIR_Op2*)op;
1249 #endif
1250
1251 LIR_Opr move_from = cmove->in_opr1();
1252 LIR_Opr move_to = cmove->result_opr();
1253
1254 if (move_to->is_register() && move_from->is_register()) {
1255 Interval* from = interval_at(reg_num(move_from));
1256 Interval* to = interval_at(reg_num(move_to));
1257 if (from != NULL && to != NULL) {
1258 to->set_register_hint(from);
1259 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", cmove->id(), from->reg_num(), to->reg_num()));
1260 }
1261 }
1262 break;
1263 }
1264 default:
1265 break;
1266 }
1267 }
1268
1269
3126
3127 sort_intervals_after_allocation();
3128
3129 DEBUG_ONLY(verify());
3130
3131 eliminate_spill_moves();
3132 assign_reg_num();
3133 CHECK_BAILOUT();
3134
3135 NOT_PRODUCT(print_lir(2, "LIR after assignment of register numbers:"));
3136 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_after_asign));
3137
3138 { TIME_LINEAR_SCAN(timer_allocate_fpu_stack);
3139
3140 if (use_fpu_stack_allocation()) {
3141 allocate_fpu_stack(); // Only has effect on Intel
3142 NOT_PRODUCT(print_lir(2, "LIR after FPU stack allocation:"));
3143 }
3144 }
3145
3146 #ifndef RISCV
3147 // Disable these optimizations on riscv temporarily, because it does not
3148 // work when the comparison operands are bound to branches or cmoves.
3149 { TIME_LINEAR_SCAN(timer_optimize_lir);
3150
3151 EdgeMoveOptimizer::optimize(ir()->code());
3152 ControlFlowOptimizer::optimize(ir()->code());
3153 // check that cfg is still correct after optimizations
3154 ir()->verify();
3155 }
3156 #endif
3157
3158 NOT_PRODUCT(print_lir(1, "Before Code Generation", false));
3159 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_final));
3160 NOT_PRODUCT(_total_timer.end_method(this));
3161 }
3162
3163
3164 // ********** Printing functions
3165
3166 #ifndef PRODUCT
3167
3168 void LinearScan::print_timers(double total) {
3169 _total_timer.print(total);
3170 }
3171
3172 void LinearScan::print_statistics() {
3173 _stat_before_alloc.print("before allocation");
3174 _stat_after_asign.print("after assignment of register");
3175 _stat_final.print("after optimization");
3176 }
6360 if (last_branch->info() == NULL) {
6361 if (last_branch->block() == code->at(i + 1)) {
6362
6363 TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id()));
6364
6365 // delete last branch instruction
6366 instructions->trunc_to(instructions->length() - 1);
6367
6368 } else {
6369 LIR_Op* prev_op = instructions->at(instructions->length() - 2);
6370 if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) {
6371 assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6372 LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
6373
6374 if (prev_branch->stub() == NULL) {
6375
6376 LIR_Op2* prev_cmp = NULL;
6377 // There might be a cmove inserted for profiling which depends on the same
6378 // compare. If we change the condition of the respective compare, we have
6379 // to take care of this cmove as well.
6380 #ifdef RISCV
6381 LIR_Op4* prev_cmove = NULL;
6382 #else
6383 LIR_Op2* prev_cmove = NULL;
6384 #endif
6385
6386 for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
6387 prev_op = instructions->at(j);
6388 // check for the cmove
6389 if (prev_op->code() == lir_cmove) {
6390 #ifdef RISCV
6391 assert(prev_op->as_Op4() != NULL, "cmove must be of type LIR_Op4");
6392 prev_cmove = (LIR_Op4*)prev_op;
6393 #else
6394 assert(prev_op->as_Op2() != NULL, "cmove must be of type LIR_Op2");
6395 prev_cmove = (LIR_Op2*)prev_op;
6396 #endif
6397 assert(prev_branch->cond() == prev_cmove->condition(), "should be the same");
6398 }
6399 if (prev_op->code() == lir_cmp) {
6400 assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
6401 prev_cmp = (LIR_Op2*)prev_op;
6402 assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
6403 }
6404 }
6405 // Guarantee because it is dereferenced below.
6406 guarantee(prev_cmp != NULL, "should have found comp instruction for branch");
6407 if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
6408
6409 TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
6410
6411 // eliminate a conditional branch to the immediate successor
6412 prev_branch->change_block(last_branch->block());
6413 prev_branch->negate_cond();
6414 prev_cmp->set_condition(prev_branch->cond());
6415 instructions->trunc_to(instructions->length() - 1);
6416 // if we do change the condition, we have to change the cmove as well
|