Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 2448113002: [arm64] Emit CBZ for deoptimisations. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/instruction-selector.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 #include "src/compiler/node-properties.h" 7 #include "src/compiler/node-properties.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 2134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 case kUnsignedLessThanOrEqual: // generate CBZ 2145 case kUnsignedLessThanOrEqual: // generate CBZ
2146 return kEqual; 2146 return kEqual;
2147 case kUnsignedGreaterThan: // generate CBNZ 2147 case kUnsignedGreaterThan: // generate CBNZ
2148 return kNotEqual; 2148 return kNotEqual;
2149 default: 2149 default:
2150 UNREACHABLE(); 2150 UNREACHABLE();
2151 return cond; 2151 return cond;
2152 } 2152 }
2153 } 2153 }
2154 2154
2155 void EmitBranchOrDeoptimize(InstructionSelector* selector,
2156 InstructionCode opcode, InstructionOperand value,
2157 FlagsContinuation* cont) {
2158 Arm64OperandGenerator g(selector);
2159 if (cont->IsBranch()) {
2160 selector->Emit(cont->Encode(opcode), g.NoOutput(), value,
2161 g.Label(cont->true_block()), g.Label(cont->false_block()));
2162 } else {
2163 DCHECK(cont->IsDeoptimize());
2164 selector->EmitDeoptimize(cont->Encode(opcode), g.NoOutput(), value,
2165 cont->reason(), cont->frame_state());
2166 }
2167 }
2168
2155 // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node} 2169 // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node}
2156 // against zero, depending on the condition. 2170 // against zero, depending on the condition.
2157 bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user, 2171 bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, Node* user,
2158 FlagsCondition cond, FlagsContinuation* cont) { 2172 FlagsCondition cond, FlagsContinuation* cont) {
2159 Int32BinopMatcher m_user(user); 2173 Int32BinopMatcher m_user(user);
2160 USE(m_user); 2174 USE(m_user);
2161 DCHECK(m_user.right().Is(0) || m_user.left().Is(0)); 2175 DCHECK(m_user.right().Is(0) || m_user.left().Is(0));
2162 2176
2163 // Only handle branches. 2177 // Only handle branches and deoptimisations.
2164 if (!cont->IsBranch()) return false; 2178 if (!cont->IsBranch() && !cont->IsDeoptimize()) return false;
2165 2179
2166 switch (cond) { 2180 switch (cond) {
2167 case kSignedLessThan: 2181 case kSignedLessThan:
2168 case kSignedGreaterThanOrEqual: { 2182 case kSignedGreaterThanOrEqual: {
2183 // We don't generate TBZ/TBNZ for deoptimisations, as they have a
2184 // shorter range than conditional branches and generating them for
2185 // deoptimisations results in more veneers.
2186 if (cont->IsDeoptimize()) return false;
2169 Arm64OperandGenerator g(selector); 2187 Arm64OperandGenerator g(selector);
2170 cont->Overwrite(MapForTbz(cond)); 2188 cont->Overwrite(MapForTbz(cond));
2171 Int32Matcher m(node); 2189 Int32Matcher m(node);
2172 if (m.IsFloat64ExtractHighWord32() && selector->CanCover(user, node)) { 2190 if (m.IsFloat64ExtractHighWord32() && selector->CanCover(user, node)) {
2173 // SignedLessThan(Float64ExtractHighWord32(x), 0) and 2191 // SignedLessThan(Float64ExtractHighWord32(x), 0) and
2174 // SignedGreaterThanOrEqual(Float64ExtractHighWord32(x), 0) essentially 2192 // SignedGreaterThanOrEqual(Float64ExtractHighWord32(x), 0) essentially
2175 // check the sign bit of a 64-bit floating point value. 2193 // check the sign bit of a 64-bit floating point value.
2176 InstructionOperand temp = g.TempRegister(); 2194 InstructionOperand temp = g.TempRegister();
2177 selector->Emit(kArm64U64MoveFloat64, temp, 2195 selector->Emit(kArm64U64MoveFloat64, temp,
2178 g.UseRegister(node->InputAt(0))); 2196 g.UseRegister(node->InputAt(0)));
2179 selector->Emit(cont->Encode(kArm64TestAndBranch), g.NoOutput(), temp, 2197 selector->Emit(cont->Encode(kArm64TestAndBranch), g.NoOutput(), temp,
2180 g.TempImmediate(63), g.Label(cont->true_block()), 2198 g.TempImmediate(63), g.Label(cont->true_block()),
2181 g.Label(cont->false_block())); 2199 g.Label(cont->false_block()));
2182 return true; 2200 return true;
2183 } 2201 }
2184 selector->Emit(cont->Encode(kArm64TestAndBranch32), g.NoOutput(), 2202 selector->Emit(cont->Encode(kArm64TestAndBranch32), g.NoOutput(),
2185 g.UseRegister(node), g.TempImmediate(31), 2203 g.UseRegister(node), g.TempImmediate(31),
2186 g.Label(cont->true_block()), g.Label(cont->false_block())); 2204 g.Label(cont->true_block()), g.Label(cont->false_block()));
2187 return true; 2205 return true;
2188 } 2206 }
2189 case kEqual: 2207 case kEqual:
2190 case kNotEqual: 2208 case kNotEqual:
2191 case kUnsignedLessThanOrEqual: 2209 case kUnsignedLessThanOrEqual:
2192 case kUnsignedGreaterThan: { 2210 case kUnsignedGreaterThan: {
2193 Arm64OperandGenerator g(selector); 2211 Arm64OperandGenerator g(selector);
2194 cont->Overwrite(MapForCbz(cond)); 2212 cont->Overwrite(MapForCbz(cond));
2195 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(), 2213 EmitBranchOrDeoptimize(selector, kArm64CompareAndBranch32,
2196 g.UseRegister(node), g.Label(cont->true_block()), 2214 g.UseRegister(node), cont);
2197 g.Label(cont->false_block()));
2198 return true; 2215 return true;
2199 } 2216 }
2200 default: 2217 default:
2201 return false; 2218 return false;
2202 } 2219 }
2203 } 2220 }
2204 2221
2205 void VisitWord32Compare(InstructionSelector* selector, Node* node, 2222 void VisitWord32Compare(InstructionSelector* selector, Node* node,
2206 FlagsContinuation* cont) { 2223 FlagsContinuation* cont) {
2207 Int32BinopMatcher m(node); 2224 Int32BinopMatcher m(node);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 // Attempt to merge the Word64Equal(Word64And(x, y), 0) comparison 2390 // Attempt to merge the Word64Equal(Word64And(x, y), 0) comparison
2374 // into a tbz/tbnz instruction. 2391 // into a tbz/tbnz instruction.
2375 if (TryEmitTestAndBranch<Uint64BinopMatcher, kArm64TestAndBranch>( 2392 if (TryEmitTestAndBranch<Uint64BinopMatcher, kArm64TestAndBranch>(
2376 selector, left, cont)) { 2393 selector, left, cont)) {
2377 return; 2394 return;
2378 } 2395 }
2379 return VisitWordCompare(selector, left, kArm64Tst, cont, true, 2396 return VisitWordCompare(selector, left, kArm64Tst, cont, true,
2380 kLogical64Imm); 2397 kLogical64Imm);
2381 } 2398 }
2382 // Merge the Word64Equal(x, 0) comparison into a cbz instruction. 2399 // Merge the Word64Equal(x, 0) comparison into a cbz instruction.
2383 if (cont->IsBranch()) { 2400 if (cont->IsBranch() || cont->IsDeoptimize()) {
2384 selector->Emit(cont->Encode(kArm64CompareAndBranch), g.NoOutput(), 2401 EmitBranchOrDeoptimize(selector,
2385 g.UseRegister(left), g.Label(cont->true_block()), 2402 cont->Encode(kArm64CompareAndBranch),
2386 g.Label(cont->false_block())); 2403 g.UseRegister(left), cont);
2387 return; 2404 return;
2388 } 2405 }
2389 } 2406 }
2390 return VisitWordCompare(selector, value, kArm64Cmp, cont, false, 2407 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
2391 kArithmeticImm); 2408 kArithmeticImm);
2392 } 2409 }
2393 case IrOpcode::kInt64LessThan: 2410 case IrOpcode::kInt64LessThan:
2394 cont->OverwriteAndNegateIfEqual(kSignedLessThan); 2411 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
2395 return VisitWordCompare(selector, value, kArm64Cmp, cont, false, 2412 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
2396 kArithmeticImm); 2413 kArithmeticImm);
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 // static 2905 // static
2889 MachineOperatorBuilder::AlignmentRequirements 2906 MachineOperatorBuilder::AlignmentRequirements
2890 InstructionSelector::AlignmentRequirements() { 2907 InstructionSelector::AlignmentRequirements() {
2891 return MachineOperatorBuilder::AlignmentRequirements:: 2908 return MachineOperatorBuilder::AlignmentRequirements::
2892 FullUnalignedAccessSupport(); 2909 FullUnalignedAccessSupport();
2893 } 2910 }
2894 2911
2895 } // namespace compiler 2912 } // namespace compiler
2896 } // namespace internal 2913 } // namespace internal
2897 } // namespace v8 2914 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/instruction-selector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698