From 4ef3e45d7c6ec3c482a1a48f4df470811aa3cf0a Mon Sep 17 00:00:00 2001 From: buzbee Date: Fri, 14 Dec 2012 13:35:28 -0800 Subject: Compiler constant handling rework In preparation for de-optimization, reworked the constant handling mechanism. Also took advantage of knowledge of constant operands (particularly for long operations). Significant performance improvements for Mandelbrot (~60 seconds to ~34 seconds). Minor improvements in other benchmarks. The new constant handling breaks two of the existing optimization passes: "Skip Large Method" and "Load/Store Elimization." I don't intend to update the large method optimization because it will be superceeded by the upcoming interpreter/ fingerprinting mechanism. Leaving the code in place for now in order to compare compile-time improvements with fingerprinting/interpret. All related code will be deleted when that is complete. The load/store elimination pass needs some rework to handle uses of multiple-register loads and stores. It will be updated & restored in a future CL. Change-Id: Ia979abaf51b8ae81bbb0428031cbcea854625fac --- src/compiler/codegen/local_optimizations.cc | 32 +++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'src/compiler/codegen/local_optimizations.cc') diff --git a/src/compiler/codegen/local_optimizations.cc b/src/compiler/codegen/local_optimizations.cc index b6981cac03..2b86421bc4 100644 --- a/src/compiler/codegen/local_optimizations.cc +++ b/src/compiler/codegen/local_optimizations.cc @@ -81,13 +81,20 @@ static void ApplyLoadStoreElimination(CompilationUnit* cu, LIR* head_lir, LIR* t if (head_lir == tail_lir) return; for (this_lir = PREV_LIR(tail_lir); this_lir != head_lir; this_lir = PREV_LIR(this_lir)) { + + if (is_pseudo_opcode(this_lir->opcode)) continue; + int sink_distance = 0; + uint64_t target_flags = cg->GetTargetInstFlags(this_lir->opcode); + /* Skip non-interesting instructions */ if ((this_lir->flags.is_nop == true) || - is_pseudo_opcode(this_lir->opcode) || - (cg->GetTargetInstFlags(this_lir->opcode) & IS_BRANCH) || - !(cg->GetTargetInstFlags(this_lir->opcode) & (IS_LOAD | IS_STORE))) { + (target_flags & IS_BRANCH) || + ((target_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) || // Skip wide loads. + ((target_flags & (REG_USE0 | REG_USE1 | REG_USE2)) == + (REG_USE0 | REG_USE1 | REG_USE2)) || // Skip wide stores. + !(target_flags & (IS_LOAD | IS_STORE))) { continue; } @@ -130,7 +137,7 @@ static void ApplyLoadStoreElimination(CompilationUnit* cu, LIR* head_lir, LIR* t * Skip already dead instructions (whose dataflow information is * outdated and misleading). */ - if (check_lir->flags.is_nop) continue; + if (check_lir->flags.is_nop || is_pseudo_opcode(check_lir->opcode)) continue; uint64_t check_mem_mask = (check_lir->use_mask | check_lir->def_mask) & ENCODE_MEM; uint64_t alias_condition = this_mem_mask & check_mem_mask; @@ -139,14 +146,18 @@ static void ApplyLoadStoreElimination(CompilationUnit* cu, LIR* head_lir, LIR* t /* * Potential aliases seen - check the alias relations */ - if (check_mem_mask != ENCODE_MEM && alias_condition != 0) { - bool is_check_lir_load = cg->GetTargetInstFlags(check_lir->opcode) & IS_LOAD; + uint64_t check_flags = cg->GetTargetInstFlags(check_lir->opcode); + // TUNING: Support instructions with multiple register targets. + if ((check_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) { + stop_here = true; + } else if (check_mem_mask != ENCODE_MEM && alias_condition != 0) { + bool is_check_lir_load = check_flags & IS_LOAD; if (alias_condition == ENCODE_LITERAL) { /* * Should only see literal loads in the instruction * stream. */ - DCHECK(!(cg->GetTargetInstFlags(check_lir->opcode) & IS_STORE)); + DCHECK(!(check_flags & IS_STORE)); /* Same value && same register type */ if (check_lir->alias_info == this_lir->alias_info && cg->SameRegType(check_lir->operands[0], native_reg_id)) { @@ -276,10 +287,13 @@ void ApplyLoadHoisting(CompilationUnit* cu, LIR* head_lir, LIR* tail_lir) /* Start from the second instruction */ for (this_lir = NEXT_LIR(head_lir); this_lir != tail_lir; this_lir = NEXT_LIR(this_lir)) { + if (is_pseudo_opcode(this_lir->opcode)) continue; + + uint64_t target_flags = cg->GetTargetInstFlags(this_lir->opcode); /* Skip non-interesting instructions */ if ((this_lir->flags.is_nop == true) || - is_pseudo_opcode(this_lir->opcode) || - !(cg->GetTargetInstFlags(this_lir->opcode) & IS_LOAD)) { + ((target_flags & (REG_DEF0 | REG_DEF1)) == (REG_DEF0 | REG_DEF1)) || + !(target_flags & IS_LOAD)) { continue; } -- cgit v1.2.3-59-g8ed1b