OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 virtual ComparisonComp* AsComparison() { return NULL; } | 219 virtual ComparisonComp* AsComparison() { return NULL; } |
220 | 220 |
221 // Create a location summary for this computation. | 221 // Create a location summary for this computation. |
222 // TODO(fschneider): Temporarily returns NULL for instructions | 222 // TODO(fschneider): Temporarily returns NULL for instructions |
223 // that are not yet converted to the location based code generation. | 223 // that are not yet converted to the location based code generation. |
224 virtual LocationSummary* MakeLocationSummary() const = 0; | 224 virtual LocationSummary* MakeLocationSummary() const = 0; |
225 | 225 |
226 // TODO(fschneider): Make EmitNativeCode and locs const. | 226 // TODO(fschneider): Make EmitNativeCode and locs const. |
227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
228 | 228 |
| 229 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 230 BranchInstr* branch) { |
| 231 UNREACHABLE(); |
| 232 } |
| 233 |
229 static LocationSummary* MakeCallSummary(); | 234 static LocationSummary* MakeCallSummary(); |
230 | 235 |
231 // Declare an enum value used to define kind-test predicates. | 236 // Declare an enum value used to define kind-test predicates. |
232 enum ComputationKind { | 237 enum ComputationKind { |
233 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, | 238 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, |
234 | 239 |
235 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) | 240 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) |
236 | 241 |
237 #undef DECLARE_COMPUTATION_KIND | 242 #undef DECLARE_COMPUTATION_KIND |
238 }; | 243 }; |
239 | 244 |
240 virtual ComputationKind computation_kind() const = 0; | 245 virtual ComputationKind computation_kind() const = 0; |
241 | 246 |
242 virtual Representation representation() const { | 247 virtual Representation representation() const { |
243 return kTagged; | 248 return kTagged; |
244 } | 249 } |
245 | 250 |
246 // Declare predicate for each computation. | 251 // Declare predicate for each computation. |
247 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 252 #define DECLARE_PREDICATE(ShortName, ClassName) \ |
248 inline bool Is##ShortName() const; \ | 253 inline bool Is##ShortName() const; \ |
249 inline const ClassName* As##ShortName() const; \ | 254 inline const ClassName* As##ShortName() const; \ |
250 inline ClassName* As##ShortName(); | 255 inline ClassName* As##ShortName(); |
251 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 256 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) |
252 #undef DECLARE_PREDICATE | 257 #undef DECLARE_PREDICATE |
253 | 258 |
254 private: | 259 private: |
| 260 friend class BranchInstr; |
| 261 |
255 intptr_t deopt_id_; | 262 intptr_t deopt_id_; |
256 const ICData* ic_data_; | 263 const ICData* ic_data_; |
257 LocationSummary* locs_; | 264 LocationSummary* locs_; |
258 | 265 |
259 DISALLOW_COPY_AND_ASSIGN(Computation); | 266 DISALLOW_COPY_AND_ASSIGN(Computation); |
260 }; | 267 }; |
261 | 268 |
262 | 269 |
263 // An embedded container with N elements of type T. Used (with partial | 270 // An embedded container with N elements of type T. Used (with partial |
264 // specialization for N=0) because embedded arrays cannot have size 0. | 271 // specialization for N=0) because embedded arrays cannot have size 0. |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 DECLARE_COMPUTATION(StrictCompare) | 811 DECLARE_COMPUTATION(StrictCompare) |
805 | 812 |
806 virtual void PrintOperandsTo(BufferFormatter* f) const; | 813 virtual void PrintOperandsTo(BufferFormatter* f) const; |
807 | 814 |
808 virtual bool CanDeoptimize() const { return false; } | 815 virtual bool CanDeoptimize() const { return false; } |
809 | 816 |
810 virtual Definition* TryReplace(BindInstr* instr) const; | 817 virtual Definition* TryReplace(BindInstr* instr) const; |
811 | 818 |
812 virtual intptr_t ResultCid() const { return kBoolCid; } | 819 virtual intptr_t ResultCid() const { return kBoolCid; } |
813 | 820 |
| 821 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 822 BranchInstr* branch); |
| 823 |
814 private: | 824 private: |
815 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 825 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
816 }; | 826 }; |
817 | 827 |
818 | 828 |
819 class EqualityCompareComp : public ComparisonComp { | 829 class EqualityCompareComp : public ComparisonComp { |
820 public: | 830 public: |
821 EqualityCompareComp(intptr_t token_pos, | 831 EqualityCompareComp(intptr_t token_pos, |
822 intptr_t try_index, | 832 intptr_t try_index, |
823 Token::Kind kind, | 833 Token::Kind kind, |
(...skipping 13 matching lines...) Expand all Loading... |
837 | 847 |
838 // Receiver class id is computed from collected ICData. | 848 // Receiver class id is computed from collected ICData. |
839 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | 849 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } |
840 intptr_t receiver_class_id() const { return receiver_class_id_; } | 850 intptr_t receiver_class_id() const { return receiver_class_id_; } |
841 | 851 |
842 virtual void PrintOperandsTo(BufferFormatter* f) const; | 852 virtual void PrintOperandsTo(BufferFormatter* f) const; |
843 | 853 |
844 virtual bool CanDeoptimize() const { return true; } | 854 virtual bool CanDeoptimize() const { return true; } |
845 virtual intptr_t ResultCid() const; | 855 virtual intptr_t ResultCid() const; |
846 | 856 |
| 857 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 858 BranchInstr* branch); |
| 859 |
847 private: | 860 private: |
848 const intptr_t token_pos_; | 861 const intptr_t token_pos_; |
849 const intptr_t try_index_; | 862 const intptr_t try_index_; |
850 intptr_t receiver_class_id_; // Set by optimizer. | 863 intptr_t receiver_class_id_; // Set by optimizer. |
851 | 864 |
852 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 865 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
853 }; | 866 }; |
854 | 867 |
855 | 868 |
856 class RelationalOpComp : public ComparisonComp { | 869 class RelationalOpComp : public ComparisonComp { |
(...skipping 21 matching lines...) Expand all Loading... |
878 operands_class_id_ = value; | 891 operands_class_id_ = value; |
879 } | 892 } |
880 | 893 |
881 intptr_t operands_class_id() const { return operands_class_id_; } | 894 intptr_t operands_class_id() const { return operands_class_id_; } |
882 | 895 |
883 virtual void PrintOperandsTo(BufferFormatter* f) const; | 896 virtual void PrintOperandsTo(BufferFormatter* f) const; |
884 | 897 |
885 virtual bool CanDeoptimize() const { return true; } | 898 virtual bool CanDeoptimize() const { return true; } |
886 virtual intptr_t ResultCid() const; | 899 virtual intptr_t ResultCid() const; |
887 | 900 |
| 901 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 902 BranchInstr* branch); |
| 903 |
888 private: | 904 private: |
889 const intptr_t token_pos_; | 905 const intptr_t token_pos_; |
890 const intptr_t try_index_; | 906 const intptr_t try_index_; |
891 intptr_t operands_class_id_; // class id of both operands. | 907 intptr_t operands_class_id_; // class id of both operands. |
892 | 908 |
893 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); | 909 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); |
894 }; | 910 }; |
895 | 911 |
896 | 912 |
897 class StaticCallComp : public TemplateComputation<0> { | 913 class StaticCallComp : public TemplateComputation<0> { |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 M(Phi) \ | 2211 M(Phi) \ |
2196 M(Bind) \ | 2212 M(Bind) \ |
2197 M(Parameter) \ | 2213 M(Parameter) \ |
2198 M(ParallelMove) \ | 2214 M(ParallelMove) \ |
2199 M(PushArgument) \ | 2215 M(PushArgument) \ |
2200 M(Return) \ | 2216 M(Return) \ |
2201 M(Throw) \ | 2217 M(Throw) \ |
2202 M(ReThrow) \ | 2218 M(ReThrow) \ |
2203 M(Goto) \ | 2219 M(Goto) \ |
2204 M(Branch) \ | 2220 M(Branch) \ |
2205 M(StrictCompareAndBranch) | |
2206 | 2221 |
2207 | 2222 |
2208 // Forward declarations for Instruction classes. | 2223 // Forward declarations for Instruction classes. |
2209 class BlockEntryInstr; | 2224 class BlockEntryInstr; |
2210 class FlowGraphBuilder; | 2225 class FlowGraphBuilder; |
2211 class Environment; | 2226 class Environment; |
2212 | 2227 |
2213 #define FORWARD_DECLARATION(type) class type##Instr; | 2228 #define FORWARD_DECLARATION(type) class type##Instr; |
2214 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 2229 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
2215 #undef FORWARD_DECLARATION | 2230 #undef FORWARD_DECLARATION |
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3205 Condition true_condition); | 3220 Condition true_condition); |
3206 | 3221 |
3207 private: | 3222 private: |
3208 TargetEntryInstr* true_successor_; | 3223 TargetEntryInstr* true_successor_; |
3209 TargetEntryInstr* false_successor_; | 3224 TargetEntryInstr* false_successor_; |
3210 | 3225 |
3211 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); | 3226 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); |
3212 }; | 3227 }; |
3213 | 3228 |
3214 | 3229 |
3215 template<intptr_t N> | 3230 class BranchInstr : public ControlInstruction { |
3216 class TemplateControlInstruction: public ControlInstruction { | |
3217 public: | 3231 public: |
3218 TemplateControlInstruction<N>() : locs_(NULL) { } | 3232 explicit BranchInstr(ComparisonComp* computation) |
3219 | 3233 : computation_(computation), locs_(NULL) { } |
3220 virtual intptr_t InputCount() const { return N; } | |
3221 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | |
3222 virtual void SetInputAt(intptr_t i, Value* value) { | |
3223 ASSERT(value != NULL); | |
3224 inputs_[i] = value; | |
3225 } | |
3226 | |
3227 virtual LocationSummary* locs() { | |
3228 if (locs_ == NULL) { | |
3229 locs_ = MakeLocationSummary(); | |
3230 } | |
3231 return locs_; | |
3232 } | |
3233 | |
3234 virtual LocationSummary* MakeLocationSummary() const = 0; | |
3235 | |
3236 protected: | |
3237 EmbeddedArray<Value*, N> inputs_; | |
3238 | |
3239 private: | |
3240 LocationSummary* locs_; | |
3241 }; | |
3242 | |
3243 | |
3244 class BranchInstr : public TemplateControlInstruction<2> { | |
3245 public: | |
3246 BranchInstr(intptr_t token_pos, | |
3247 intptr_t try_index, | |
3248 Value* left, | |
3249 Value* right, | |
3250 Token::Kind kind) | |
3251 : deopt_id_(Isolate::kNoDeoptId), | |
3252 ic_data_(NULL), | |
3253 token_pos_(token_pos), | |
3254 try_index_(try_index), | |
3255 kind_(kind) { | |
3256 ASSERT(left != NULL); | |
3257 ASSERT(right != NULL); | |
3258 inputs_[0] = left; | |
3259 inputs_[1] = right; | |
3260 ASSERT(!Token::IsStrictEqualityOperator(kind)); | |
3261 ASSERT(Token::IsEqualityOperator(kind) || | |
3262 Token::IsRelationalOperator(kind) || | |
3263 Token::IsTypeTestOperator(kind)); | |
3264 Isolate* isolate = Isolate::Current(); | |
3265 deopt_id_ = isolate->GetNextDeoptId(); | |
3266 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); | |
3267 } | |
3268 | 3234 |
3269 DECLARE_INSTRUCTION(Branch) | 3235 DECLARE_INSTRUCTION(Branch) |
3270 | 3236 |
3271 Value* left() const { return inputs_[0]; } | 3237 virtual intptr_t ArgumentCount() const { |
3272 Value* right() const { return inputs_[1]; } | 3238 return computation()->ArgumentCount(); |
| 3239 } |
| 3240 intptr_t InputCount() const { return computation()->InputCount(); } |
3273 | 3241 |
3274 virtual intptr_t ArgumentCount() const { return 0; } | 3242 Value* InputAt(intptr_t i) const { return computation()->InputAt(i); } |
3275 | 3243 |
3276 Token::Kind kind() const { return kind_; } | 3244 void SetInputAt(intptr_t i, Value* value) { |
3277 | 3245 computation()->SetInputAt(i, value); |
3278 intptr_t deopt_id() const { return deopt_id_; } | |
3279 | |
3280 const ICData* ic_data() const { return ic_data_; } | |
3281 bool HasICData() const { | |
3282 return (ic_data() != NULL) && !ic_data()->IsNull(); | |
3283 } | 3246 } |
3284 | 3247 |
3285 intptr_t token_pos() const { return token_pos_;} | 3248 virtual bool CanDeoptimize() const { return computation()->CanDeoptimize(); } |
3286 intptr_t try_index() const { return try_index_; } | |
3287 | 3249 |
3288 virtual LocationSummary* MakeLocationSummary() const; | 3250 ComparisonComp* computation() const { return computation_; } |
| 3251 void set_computation(ComparisonComp* value) { computation_ = value; } |
3289 | 3252 |
3290 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 3253 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
3291 | 3254 |
3292 virtual bool CanDeoptimize() const { return true; } | 3255 virtual LocationSummary* locs() { |
| 3256 if (computation_->locs_ == NULL) { |
| 3257 LocationSummary* summary = computation_->MakeLocationSummary(); |
| 3258 // Branches don't produce a result. |
| 3259 summary->set_out(Location::NoLocation()); |
| 3260 computation_->locs_ = summary; |
| 3261 } |
| 3262 return computation_->locs_; |
| 3263 } |
3293 | 3264 |
3294 private: | 3265 private: |
3295 intptr_t deopt_id_; | 3266 ComparisonComp* computation_; |
3296 const ICData* ic_data_; | 3267 LocationSummary* locs_; |
3297 const intptr_t token_pos_; | |
3298 const intptr_t try_index_; | |
3299 const Token::Kind kind_; | |
3300 | 3268 |
3301 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 3269 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
3302 }; | 3270 }; |
3303 | 3271 |
3304 | 3272 |
3305 class StrictCompareAndBranchInstr : public TemplateControlInstruction<2> { | |
3306 public: | |
3307 StrictCompareAndBranchInstr(Value* left, Value* right, Token::Kind kind) | |
3308 : kind_(kind) { | |
3309 ASSERT(left != NULL); | |
3310 ASSERT(right != NULL); | |
3311 inputs_[0] = left; | |
3312 inputs_[1] = right; | |
3313 ASSERT(Token::IsStrictEqualityOperator(kind)); | |
3314 } | |
3315 | |
3316 DECLARE_INSTRUCTION(StrictCompareAndBranch) | |
3317 | |
3318 Value* left() const { return inputs_[0]; } | |
3319 Value* right() const { return inputs_[1]; } | |
3320 | |
3321 virtual intptr_t ArgumentCount() const { return 0; } | |
3322 | |
3323 Token::Kind kind() const { return kind_; } | |
3324 | |
3325 virtual LocationSummary* MakeLocationSummary() const; | |
3326 | |
3327 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
3328 | |
3329 virtual bool CanDeoptimize() const { return false; } | |
3330 | |
3331 private: | |
3332 const Token::Kind kind_; | |
3333 | |
3334 DISALLOW_COPY_AND_ASSIGN(StrictCompareAndBranchInstr); | |
3335 }; | |
3336 | |
3337 | |
3338 #undef DECLARE_INSTRUCTION | 3273 #undef DECLARE_INSTRUCTION |
3339 | 3274 |
3340 | 3275 |
3341 class Environment : public ZoneAllocated { | 3276 class Environment : public ZoneAllocated { |
3342 public: | 3277 public: |
3343 // Construct an environment by constructing uses from an array of definitions. | 3278 // Construct an environment by constructing uses from an array of definitions. |
3344 Environment(const GrowableArray<Definition*>& definitions, | 3279 Environment(const GrowableArray<Definition*>& definitions, |
3345 intptr_t fixed_parameter_count); | 3280 intptr_t fixed_parameter_count); |
3346 | 3281 |
3347 void set_locations(Location* locations) { | 3282 void set_locations(Location* locations) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3424 ForwardInstructionIterator* current_iterator_; | 3359 ForwardInstructionIterator* current_iterator_; |
3425 | 3360 |
3426 private: | 3361 private: |
3427 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3362 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
3428 }; | 3363 }; |
3429 | 3364 |
3430 | 3365 |
3431 } // namespace dart | 3366 } // namespace dart |
3432 | 3367 |
3433 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3368 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |