| 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 |