OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 private: | 2121 private: |
2122 JoinEntryInstr* successor_; | 2122 JoinEntryInstr* successor_; |
2123 double edge_weight_; | 2123 double edge_weight_; |
2124 | 2124 |
2125 // Parallel move that will be used by linear scan register allocator to | 2125 // Parallel move that will be used by linear scan register allocator to |
2126 // connect live ranges at the end of the block and resolve phis. | 2126 // connect live ranges at the end of the block and resolve phis. |
2127 ParallelMoveInstr* parallel_move_; | 2127 ParallelMoveInstr* parallel_move_; |
2128 }; | 2128 }; |
2129 | 2129 |
2130 | 2130 |
| 2131 template<intptr_t N> |
| 2132 class TemplateDefinition : public Definition { |
| 2133 public: |
| 2134 TemplateDefinition<N>() : locs_(NULL) { } |
| 2135 |
| 2136 virtual intptr_t InputCount() const { return N; } |
| 2137 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
| 2138 |
| 2139 // Returns a structure describing the location constraints required |
| 2140 // to emit native code for this definition. |
| 2141 LocationSummary* locs() { |
| 2142 if (locs_ == NULL) { |
| 2143 locs_ = MakeLocationSummary(); |
| 2144 } |
| 2145 return locs_; |
| 2146 } |
| 2147 |
| 2148 protected: |
| 2149 EmbeddedArray<Value*, N> inputs_; |
| 2150 |
| 2151 private: |
| 2152 friend class BranchInstr; |
| 2153 |
| 2154 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 2155 inputs_[i] = value; |
| 2156 } |
| 2157 |
| 2158 LocationSummary* locs_; |
| 2159 }; |
| 2160 |
| 2161 |
| 2162 class ComparisonInstr : public TemplateDefinition<2> { |
| 2163 public: |
| 2164 Value* left() const { return inputs_[0]; } |
| 2165 Value* right() const { return inputs_[1]; } |
| 2166 |
| 2167 virtual ComparisonInstr* AsComparison() { return this; } |
| 2168 |
| 2169 intptr_t token_pos() const { return token_pos_; } |
| 2170 Token::Kind kind() const { return kind_; } |
| 2171 |
| 2172 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2173 BranchInstr* branch) = 0; |
| 2174 |
| 2175 void SetDeoptId(intptr_t deopt_id) { |
| 2176 deopt_id_ = deopt_id; |
| 2177 } |
| 2178 |
| 2179 // Operation class id is computed from collected ICData. |
| 2180 void set_operation_cid(intptr_t value) { operation_cid_ = value; } |
| 2181 intptr_t operation_cid() const { return operation_cid_; } |
| 2182 |
| 2183 void NegateComparison() { |
| 2184 kind_ = Token::NegateComparison(kind_); |
| 2185 } |
| 2186 |
| 2187 protected: |
| 2188 ComparisonInstr(intptr_t token_pos, |
| 2189 Token::Kind kind, |
| 2190 Value* left, |
| 2191 Value* right) |
| 2192 : token_pos_(token_pos), kind_(kind), operation_cid_(kIllegalCid) { |
| 2193 SetInputAt(0, left); |
| 2194 SetInputAt(1, right); |
| 2195 } |
| 2196 |
| 2197 private: |
| 2198 const intptr_t token_pos_; |
| 2199 Token::Kind kind_; |
| 2200 intptr_t operation_cid_; // Set by optimizer. |
| 2201 |
| 2202 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); |
| 2203 }; |
| 2204 |
| 2205 |
2131 class BranchInstr : public Instruction { | 2206 class BranchInstr : public Instruction { |
2132 public: | 2207 public: |
2133 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false); | 2208 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false); |
2134 | 2209 |
2135 DECLARE_INSTRUCTION(Branch) | 2210 DECLARE_INSTRUCTION(Branch) |
2136 | 2211 |
2137 virtual intptr_t ArgumentCount() const; | 2212 virtual intptr_t ArgumentCount() const { |
2138 intptr_t InputCount() const; | 2213 return comparison()->ArgumentCount(); |
2139 Value* InputAt(intptr_t i) const; | 2214 } |
2140 virtual bool CanDeoptimize() const; | |
2141 virtual bool CanBecomeDeoptimizationTarget() const; | |
2142 | 2215 |
2143 virtual EffectSet Effects() const; | 2216 intptr_t InputCount() const { return comparison()->InputCount(); } |
| 2217 |
| 2218 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } |
| 2219 |
| 2220 virtual bool CanDeoptimize() const { |
| 2221 // Branches need a deoptimization info in checked mode if they |
| 2222 // can throw a type check error. |
| 2223 return comparison()->CanDeoptimize() || is_checked(); |
| 2224 } |
| 2225 |
| 2226 virtual bool CanBecomeDeoptimizationTarget() const { |
| 2227 return comparison()->CanBecomeDeoptimizationTarget(); |
| 2228 } |
| 2229 |
| 2230 virtual EffectSet Effects() const { |
| 2231 return comparison()->Effects(); |
| 2232 } |
2144 | 2233 |
2145 ComparisonInstr* comparison() const { return comparison_; } | 2234 ComparisonInstr* comparison() const { return comparison_; } |
2146 void SetComparison(ComparisonInstr* comp); | 2235 void SetComparison(ComparisonInstr* comp); |
2147 | 2236 |
2148 bool is_checked() const { return is_checked_; } | 2237 bool is_checked() const { return is_checked_; } |
2149 | 2238 |
2150 virtual LocationSummary* locs(); | 2239 virtual LocationSummary* locs() { |
2151 virtual intptr_t DeoptimizationTarget() const; | 2240 if (comparison()->locs_ == NULL) { |
2152 virtual Representation RequiredInputRepresentation(intptr_t i) const; | 2241 LocationSummary* summary = comparison()->MakeLocationSummary(); |
| 2242 // Branches don't produce a result. |
| 2243 summary->set_out(Location::NoLocation()); |
| 2244 comparison()->locs_ = summary; |
| 2245 } |
| 2246 return comparison()->locs_; |
| 2247 } |
| 2248 |
| 2249 virtual intptr_t DeoptimizationTarget() const { |
| 2250 return comparison()->DeoptimizationTarget(); |
| 2251 } |
| 2252 |
| 2253 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
| 2254 return comparison()->RequiredInputRepresentation(i); |
| 2255 } |
2153 | 2256 |
2154 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 2257 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
2155 | 2258 |
2156 virtual void PrintTo(BufferFormatter* f) const; | 2259 virtual void PrintTo(BufferFormatter* f) const; |
2157 | 2260 |
2158 // Set compile type constrained by the comparison of this branch. | 2261 // Set compile type constrained by the comparison of this branch. |
2159 // FlowGraphPropagator propagates it downwards into either true or false | 2262 // FlowGraphPropagator propagates it downwards into either true or false |
2160 // successor. | 2263 // successor. |
2161 void set_constrained_type(ConstrainedCompileType* type) { | 2264 void set_constrained_type(ConstrainedCompileType* type) { |
2162 constrained_type_ = type; | 2265 constrained_type_ = type; |
2163 } | 2266 } |
2164 | 2267 |
2165 // Return compile type constrained by the comparison of this branch. | 2268 // Return compile type constrained by the comparison of this branch. |
2166 ConstrainedCompileType* constrained_type() const { | 2269 ConstrainedCompileType* constrained_type() const { |
2167 return constrained_type_; | 2270 return constrained_type_; |
2168 } | 2271 } |
2169 | 2272 |
2170 void set_constant_target(TargetEntryInstr* target) { | 2273 void set_constant_target(TargetEntryInstr* target) { |
2171 ASSERT(target == true_successor() || target == false_successor()); | 2274 ASSERT(target == true_successor() || target == false_successor()); |
2172 constant_target_ = target; | 2275 constant_target_ = target; |
2173 } | 2276 } |
2174 TargetEntryInstr* constant_target() const { | 2277 TargetEntryInstr* constant_target() const { |
2175 return constant_target_; | 2278 return constant_target_; |
2176 } | 2279 } |
2177 | 2280 |
2178 virtual void InheritDeoptTarget(Instruction* other); | 2281 virtual void InheritDeoptTarget(Instruction* other); |
2179 | 2282 |
2180 virtual bool MayThrow() const; | 2283 virtual bool MayThrow() const { |
| 2284 return comparison()->MayThrow(); |
| 2285 } |
2181 | 2286 |
2182 TargetEntryInstr* true_successor() const { return true_successor_; } | 2287 TargetEntryInstr* true_successor() const { return true_successor_; } |
2183 TargetEntryInstr* false_successor() const { return false_successor_; } | 2288 TargetEntryInstr* false_successor() const { return false_successor_; } |
2184 | 2289 |
2185 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 2290 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
2186 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 2291 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
2187 | 2292 |
2188 virtual intptr_t SuccessorCount() const; | 2293 virtual intptr_t SuccessorCount() const; |
2189 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2294 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
2190 | 2295 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 | 2327 |
2223 virtual EffectSet Effects() const { return EffectSet::None(); } | 2328 virtual EffectSet Effects() const { return EffectSet::None(); } |
2224 | 2329 |
2225 virtual bool MayThrow() const { return false; } | 2330 virtual bool MayThrow() const { return false; } |
2226 | 2331 |
2227 private: | 2332 private: |
2228 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); | 2333 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); |
2229 }; | 2334 }; |
2230 | 2335 |
2231 | 2336 |
2232 template<intptr_t N> | |
2233 class TemplateDefinition : public Definition { | |
2234 public: | |
2235 TemplateDefinition<N>() : locs_(NULL) { } | |
2236 | |
2237 virtual intptr_t InputCount() const { return N; } | |
2238 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | |
2239 | |
2240 // Returns a structure describing the location constraints required | |
2241 // to emit native code for this definition. | |
2242 LocationSummary* locs() { | |
2243 if (locs_ == NULL) { | |
2244 locs_ = MakeLocationSummary(); | |
2245 } | |
2246 return locs_; | |
2247 } | |
2248 | |
2249 protected: | |
2250 EmbeddedArray<Value*, N> inputs_; | |
2251 | |
2252 private: | |
2253 friend class BranchInstr; | |
2254 | |
2255 virtual void RawSetInputAt(intptr_t i, Value* value) { | |
2256 inputs_[i] = value; | |
2257 } | |
2258 | |
2259 LocationSummary* locs_; | |
2260 }; | |
2261 | |
2262 | |
2263 class RedefinitionInstr : public TemplateDefinition<1> { | 2337 class RedefinitionInstr : public TemplateDefinition<1> { |
2264 public: | 2338 public: |
2265 explicit RedefinitionInstr(Value* value) { | 2339 explicit RedefinitionInstr(Value* value) { |
2266 SetInputAt(0, value); | 2340 SetInputAt(0, value); |
2267 } | 2341 } |
2268 | 2342 |
2269 DECLARE_INSTRUCTION(Redefinition) | 2343 DECLARE_INSTRUCTION(Redefinition) |
2270 | 2344 |
2271 Value* value() const { return inputs_[0]; } | 2345 Value* value() const { return inputs_[0]; } |
2272 | 2346 |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2800 | 2874 |
2801 private: | 2875 private: |
2802 InstanceCallInstr* instance_call_; | 2876 InstanceCallInstr* instance_call_; |
2803 const ICData& ic_data_; | 2877 const ICData& ic_data_; |
2804 const bool with_checks_; | 2878 const bool with_checks_; |
2805 | 2879 |
2806 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2880 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
2807 }; | 2881 }; |
2808 | 2882 |
2809 | 2883 |
2810 class ComparisonInstr : public TemplateDefinition<2> { | |
2811 public: | |
2812 Value* left() const { return inputs_[0]; } | |
2813 Value* right() const { return inputs_[1]; } | |
2814 | |
2815 virtual ComparisonInstr* AsComparison() { return this; } | |
2816 | |
2817 intptr_t token_pos() const { return token_pos_; } | |
2818 Token::Kind kind() const { return kind_; } | |
2819 | |
2820 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | |
2821 BranchInstr* branch) = 0; | |
2822 | |
2823 void SetDeoptId(intptr_t deopt_id) { | |
2824 deopt_id_ = deopt_id; | |
2825 } | |
2826 | |
2827 // Operation class id is computed from collected ICData. | |
2828 void set_operation_cid(intptr_t value) { operation_cid_ = value; } | |
2829 intptr_t operation_cid() const { return operation_cid_; } | |
2830 | |
2831 void NegateComparison() { | |
2832 kind_ = Token::NegateComparison(kind_); | |
2833 } | |
2834 | |
2835 protected: | |
2836 ComparisonInstr(intptr_t token_pos, | |
2837 Token::Kind kind, | |
2838 Value* left, | |
2839 Value* right) | |
2840 : token_pos_(token_pos), kind_(kind), operation_cid_(kIllegalCid) { | |
2841 SetInputAt(0, left); | |
2842 SetInputAt(1, right); | |
2843 } | |
2844 | |
2845 private: | |
2846 const intptr_t token_pos_; | |
2847 Token::Kind kind_; | |
2848 intptr_t operation_cid_; // Set by optimizer. | |
2849 | |
2850 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); | |
2851 }; | |
2852 | |
2853 | |
2854 // Inlined functions from class BranchInstr that forward to their comparison. | |
2855 inline intptr_t BranchInstr::ArgumentCount() const { | |
2856 return comparison()->ArgumentCount(); | |
2857 } | |
2858 | |
2859 | |
2860 inline intptr_t BranchInstr::InputCount() const { | |
2861 return comparison()->InputCount(); | |
2862 } | |
2863 | |
2864 | |
2865 inline Value* BranchInstr::InputAt(intptr_t i) const { | |
2866 return comparison()->InputAt(i); | |
2867 } | |
2868 | |
2869 | |
2870 inline bool BranchInstr::CanDeoptimize() const { | |
2871 // Branches need a deoptimization info in checked mode if they | |
2872 // can throw a type check error. | |
2873 return comparison()->CanDeoptimize() || is_checked(); | |
2874 } | |
2875 | |
2876 | |
2877 inline bool BranchInstr::CanBecomeDeoptimizationTarget() const { | |
2878 return comparison()->CanBecomeDeoptimizationTarget(); | |
2879 } | |
2880 | |
2881 | |
2882 inline EffectSet BranchInstr::Effects() const { | |
2883 return comparison()->Effects(); | |
2884 } | |
2885 | |
2886 | |
2887 inline LocationSummary* BranchInstr::locs() { | |
2888 if (comparison()->locs_ == NULL) { | |
2889 LocationSummary* summary = comparison()->MakeLocationSummary(); | |
2890 // Branches don't produce a result. | |
2891 summary->set_out(Location::NoLocation()); | |
2892 comparison()->locs_ = summary; | |
2893 } | |
2894 return comparison()->locs_; | |
2895 } | |
2896 | |
2897 | |
2898 inline intptr_t BranchInstr::DeoptimizationTarget() const { | |
2899 return comparison()->DeoptimizationTarget(); | |
2900 } | |
2901 | |
2902 | |
2903 inline Representation BranchInstr::RequiredInputRepresentation( | |
2904 intptr_t i) const { | |
2905 return comparison()->RequiredInputRepresentation(i); | |
2906 } | |
2907 | |
2908 | |
2909 inline bool BranchInstr::MayThrow() const { | |
2910 return comparison()->MayThrow(); | |
2911 } | |
2912 | |
2913 | |
2914 class StrictCompareInstr : public ComparisonInstr { | 2884 class StrictCompareInstr : public ComparisonInstr { |
2915 public: | 2885 public: |
2916 StrictCompareInstr(intptr_t token_pos, | 2886 StrictCompareInstr(intptr_t token_pos, |
2917 Token::Kind kind, | 2887 Token::Kind kind, |
2918 Value* left, | 2888 Value* left, |
2919 Value* right); | 2889 Value* right); |
2920 | 2890 |
2921 DECLARE_INSTRUCTION(StrictCompare) | 2891 DECLARE_INSTRUCTION(StrictCompare) |
2922 virtual CompileType ComputeType() const; | 2892 virtual CompileType ComputeType() const; |
2923 | 2893 |
(...skipping 3999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6923 ForwardInstructionIterator* current_iterator_; | 6893 ForwardInstructionIterator* current_iterator_; |
6924 | 6894 |
6925 private: | 6895 private: |
6926 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 6896 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
6927 }; | 6897 }; |
6928 | 6898 |
6929 | 6899 |
6930 } // namespace dart | 6900 } // namespace dart |
6931 | 6901 |
6932 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 6902 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |