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

Unified Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 2183923003: [stubs,interpreter] Optimise SMI loading for 64-bit targets. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Optimizing SMI loads at code stub assembler level. Created 4 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/arm64/instruction-scheduler-arm64.cc ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/arm64/instruction-selector-arm64.cc
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index ad3512339b39448f7698e4cc16f29c02f85380c6..f14da4f7cd1d41fe2e7b53876a6b22f91de5ce9c 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -161,7 +161,6 @@ void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
g.UseOperand(node->InputAt(1), operand_mode));
}
-
bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
Node* input_node, InstructionCode* opcode, bool try_ror) {
Arm64OperandGenerator g(selector);
@@ -458,18 +457,43 @@ int32_t LeftShiftForReducedMultiply(Matcher* m) {
} // namespace
-
-void InstructionSelector::VisitLoad(Node* node) {
- LoadRepresentation load_rep = LoadRepresentationOf(node->op());
- MachineRepresentation rep = load_rep.representation();
- Arm64OperandGenerator g(this);
+void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode,
+ ImmediateMode immediate_mode, MachineRepresentation rep,
+ Node* output = nullptr) {
+ Arm64OperandGenerator g(selector);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
- InstructionCode opcode = kArchNop;
- ImmediateMode immediate_mode = kNoImmediate;
InstructionOperand inputs[3];
size_t input_count = 0;
InstructionOperand outputs[1];
+
+ // If output is not nullptr, use that as the output register. This
+ // is used when we merge a conversion into the load.
+ outputs[0] = g.DefineAsRegister(output == nullptr ? node : output);
+ inputs[0] = g.UseRegister(base);
+
+ if (g.CanBeImmediate(index, immediate_mode)) {
+ input_count = 2;
+ inputs[1] = g.UseImmediate(index);
+ opcode |= AddressingModeField::encode(kMode_MRI);
+ } else if (TryMatchLoadStoreShift(&g, selector, rep, node, index, &inputs[1],
+ &inputs[2])) {
+ input_count = 3;
+ opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
+ } else {
+ input_count = 2;
+ inputs[1] = g.UseRegister(index);
+ opcode |= AddressingModeField::encode(kMode_MRR);
+ }
+
+ selector->Emit(opcode, arraysize(outputs), outputs, input_count, inputs);
+}
+
+void InstructionSelector::VisitLoad(Node* node) {
+ InstructionCode opcode = kArchNop;
+ ImmediateMode immediate_mode = kNoImmediate;
+ LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+ MachineRepresentation rep = load_rep.representation();
switch (rep) {
case MachineRepresentation::kFloat32:
opcode = kArm64LdrS;
@@ -502,25 +526,7 @@ void InstructionSelector::VisitLoad(Node* node) {
UNREACHABLE();
return;
}
-
- outputs[0] = g.DefineAsRegister(node);
- inputs[0] = g.UseRegister(base);
-
- if (g.CanBeImmediate(index, immediate_mode)) {
- input_count = 2;
- inputs[1] = g.UseImmediate(index);
- opcode |= AddressingModeField::encode(kMode_MRI);
- } else if (TryMatchLoadStoreShift(&g, this, rep, node, index, &inputs[1],
- &inputs[2])) {
- input_count = 3;
- opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
- } else {
- input_count = 2;
- inputs[1] = g.UseRegister(index);
- opcode |= AddressingModeField::encode(kMode_MRR);
- }
-
- Emit(opcode, arraysize(outputs), outputs, input_count, inputs);
+ EmitLoad(this, node, opcode, immediate_mode, rep);
}
@@ -959,7 +965,7 @@ void InstructionSelector::VisitWord64Shl(Node* node) {
Arm64OperandGenerator g(this);
Int64BinopMatcher m(node);
if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
- m.right().IsInRange(32, 63)) {
+ m.right().IsInRange(32, 63) && CanCover(node, m.left().node())) {
// There's no need to sign/zero-extend to 64-bit if we shift out the upper
// 32 bits anyway.
Emit(kArm64Lsl, g.DefineAsRegister(node),
@@ -1563,7 +1569,35 @@ void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
- VisitRR(this, kArm64Sxtw, node);
+ Node* value = node->InputAt(0);
+ if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) {
+ // Generate sign-extending load.
+ LoadRepresentation load_rep = LoadRepresentationOf(value->op());
+ MachineRepresentation rep = load_rep.representation();
+ InstructionCode opcode = kArchNop;
+ ImmediateMode immediate_mode = kNoImmediate;
+ switch (rep) {
+ case MachineRepresentation::kBit: // Fall through.
+ case MachineRepresentation::kWord8:
+ opcode = load_rep.IsSigned() ? kArm64Ldrsb : kArm64Ldrb;
+ immediate_mode = kLoadStoreImm8;
+ break;
+ case MachineRepresentation::kWord16:
+ opcode = load_rep.IsSigned() ? kArm64Ldrsh : kArm64Ldrh;
+ immediate_mode = kLoadStoreImm16;
+ break;
+ case MachineRepresentation::kWord32:
+ opcode = kArm64Ldrsw;
+ immediate_mode = kLoadStoreImm32;
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+ EmitLoad(this, value, opcode, immediate_mode, rep, node);
+ } else {
+ VisitRR(this, kArm64Sxtw, node);
+ }
}
« no previous file with comments | « src/compiler/arm64/instruction-scheduler-arm64.cc ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698