1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/instruction-scheduler.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
SchedulerSupported()11 bool InstructionScheduler::SchedulerSupported() { return true; }
12 
13 
GetTargetInstructionFlags(const Instruction * instr) const14 int InstructionScheduler::GetTargetInstructionFlags(
15     const Instruction* instr) const {
16   switch (instr->arch_opcode()) {
17     case kIA32Add:
18     case kIA32And:
19     case kIA32Cmp:
20     case kIA32Cmp16:
21     case kIA32Cmp8:
22     case kIA32Test:
23     case kIA32Test16:
24     case kIA32Test8:
25     case kIA32Or:
26     case kIA32Xor:
27     case kIA32Sub:
28     case kIA32Imul:
29     case kIA32ImulHigh:
30     case kIA32UmulHigh:
31     case kIA32Not:
32     case kIA32Neg:
33     case kIA32Shl:
34     case kIA32Shr:
35     case kIA32Sar:
36     case kIA32AddPair:
37     case kIA32SubPair:
38     case kIA32MulPair:
39     case kIA32ShlPair:
40     case kIA32ShrPair:
41     case kIA32SarPair:
42     case kIA32Ror:
43     case kIA32Lzcnt:
44     case kIA32Tzcnt:
45     case kIA32Popcnt:
46     case kIA32Lea:
47     case kSSEFloat32Cmp:
48     case kSSEFloat32Add:
49     case kSSEFloat32Sub:
50     case kSSEFloat32Mul:
51     case kSSEFloat32Div:
52     case kSSEFloat32Abs:
53     case kSSEFloat32Neg:
54     case kSSEFloat32Sqrt:
55     case kSSEFloat32Round:
56     case kSSEFloat64Cmp:
57     case kSSEFloat64Add:
58     case kSSEFloat64Sub:
59     case kSSEFloat64Mul:
60     case kSSEFloat64Div:
61     case kSSEFloat64Mod:
62     case kSSEFloat32Max:
63     case kSSEFloat64Max:
64     case kSSEFloat32Min:
65     case kSSEFloat64Min:
66     case kSSEFloat64Abs:
67     case kSSEFloat64Neg:
68     case kSSEFloat64Sqrt:
69     case kSSEFloat64Round:
70     case kSSEFloat32ToFloat64:
71     case kSSEFloat64ToFloat32:
72     case kSSEFloat32ToInt32:
73     case kSSEFloat32ToUint32:
74     case kSSEFloat64ToInt32:
75     case kSSEFloat64ToUint32:
76     case kSSEInt32ToFloat32:
77     case kSSEUint32ToFloat32:
78     case kSSEInt32ToFloat64:
79     case kSSEUint32ToFloat64:
80     case kSSEFloat64ExtractLowWord32:
81     case kSSEFloat64ExtractHighWord32:
82     case kSSEFloat64InsertLowWord32:
83     case kSSEFloat64InsertHighWord32:
84     case kSSEFloat64LoadLowWord32:
85     case kSSEFloat64SilenceNaN:
86     case kAVXFloat32Add:
87     case kAVXFloat32Sub:
88     case kAVXFloat32Mul:
89     case kAVXFloat32Div:
90     case kAVXFloat64Add:
91     case kAVXFloat64Sub:
92     case kAVXFloat64Mul:
93     case kAVXFloat64Div:
94     case kAVXFloat64Abs:
95     case kAVXFloat64Neg:
96     case kAVXFloat32Abs:
97     case kAVXFloat32Neg:
98     case kIA32BitcastFI:
99     case kIA32BitcastIF:
100       return (instr->addressing_mode() == kMode_None)
101           ? kNoOpcodeFlags
102           : kIsLoadOperation | kHasSideEffect;
103 
104     case kIA32Idiv:
105     case kIA32Udiv:
106       return (instr->addressing_mode() == kMode_None)
107                  ? kMayNeedDeoptCheck
108                  : kMayNeedDeoptCheck | kIsLoadOperation | kHasSideEffect;
109 
110     case kIA32Movsxbl:
111     case kIA32Movzxbl:
112     case kIA32Movb:
113     case kIA32Movsxwl:
114     case kIA32Movzxwl:
115     case kIA32Movw:
116     case kIA32Movl:
117     case kIA32Movss:
118     case kIA32Movsd:
119       // Moves are used for memory load/store operations.
120       return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
121 
122     case kIA32StackCheck:
123       return kIsLoadOperation;
124 
125     case kIA32Push:
126     case kIA32PushFloat32:
127     case kIA32PushFloat64:
128     case kIA32Poke:
129       return kHasSideEffect;
130 
131     case kIA32Xchgb:
132     case kIA32Xchgw:
133     case kIA32Xchgl:
134       return kIsLoadOperation | kHasSideEffect;
135 
136 #define CASE(Name) case k##Name:
137     COMMON_ARCH_OPCODE_LIST(CASE)
138 #undef CASE
139       // Already covered in architecture independent code.
140       UNREACHABLE();
141   }
142 
143   UNREACHABLE();
144   return kNoOpcodeFlags;
145 }
146 
147 
GetInstructionLatency(const Instruction * instr)148 int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
149   // Basic latency modeling for ia32 instructions. They have been determined
150   // in an empirical way.
151   switch (instr->arch_opcode()) {
152     case kCheckedLoadInt8:
153     case kCheckedLoadUint8:
154     case kCheckedLoadInt16:
155     case kCheckedLoadUint16:
156     case kCheckedLoadWord32:
157     case kCheckedLoadFloat32:
158     case kCheckedLoadFloat64:
159     case kCheckedStoreWord8:
160     case kCheckedStoreWord16:
161     case kCheckedStoreWord32:
162     case kCheckedStoreFloat32:
163     case kCheckedStoreFloat64:
164     case kSSEFloat64Mul:
165       return 5;
166     case kIA32Imul:
167     case kIA32ImulHigh:
168       return 5;
169     case kSSEFloat32Cmp:
170     case kSSEFloat64Cmp:
171       return 9;
172     case kSSEFloat32Add:
173     case kSSEFloat32Sub:
174     case kSSEFloat32Abs:
175     case kSSEFloat32Neg:
176     case kSSEFloat64Add:
177     case kSSEFloat64Sub:
178     case kSSEFloat64Max:
179     case kSSEFloat64Min:
180     case kSSEFloat64Abs:
181     case kSSEFloat64Neg:
182       return 5;
183     case kSSEFloat32Mul:
184       return 4;
185     case kSSEFloat32ToFloat64:
186     case kSSEFloat64ToFloat32:
187       return 6;
188     case kSSEFloat32Round:
189     case kSSEFloat64Round:
190     case kSSEFloat32ToInt32:
191     case kSSEFloat64ToInt32:
192       return 8;
193     case kSSEFloat32ToUint32:
194       return 21;
195     case kSSEFloat64ToUint32:
196       return 15;
197     case kIA32Idiv:
198       return 33;
199     case kIA32Udiv:
200       return 26;
201     case kSSEFloat32Div:
202       return 35;
203     case kSSEFloat64Div:
204       return 63;
205     case kSSEFloat32Sqrt:
206     case kSSEFloat64Sqrt:
207       return 25;
208     case kSSEFloat64Mod:
209       return 50;
210     case kArchTruncateDoubleToI:
211       return 9;
212     default:
213       return 1;
214   }
215 }
216 
217 }  // namespace compiler
218 }  // namespace internal
219 }  // namespace v8
220