Browse Source

[analyzer] semi propagate null values

We don't want to actually move them within the AST as that would likely cause problems with native compilation in may cases. We can however keep track of them and use them for data flow analysis, so something like `var x = null; if ("foo" == x) { }` can get optimized.
Simon Krajewski 8 years ago
parent
commit
e41aa3461c
1 changed files with 7 additions and 2 deletions
  1. 7 2
      src/optimization/analyzer.ml

+ 7 - 2
src/optimization/analyzer.ml

@@ -348,6 +348,7 @@ module ConstPropagation = DataFlow(struct
 	type t =
 	type t =
 		| Top
 		| Top
 		| Bottom
 		| Bottom
+		| Null of Type.t
 		| Const of tconstant
 		| Const of tconstant
 		| EnumValue of int * t list
 		| EnumValue of int * t list
 
 
@@ -365,6 +366,7 @@ module ConstPropagation = DataFlow(struct
 	let equals lat1 lat2 = match lat1,lat2 with
 	let equals lat1 lat2 = match lat1,lat2 with
 		| Top,Top | Bottom,Bottom -> true
 		| Top,Top | Bottom,Bottom -> true
 		| Const ct1,Const ct2 -> ct1 = ct2
 		| Const ct1,Const ct2 -> ct1 = ct2
+		| Null t1,Null t2 -> t1 == t2
 		| EnumValue(i1,_),EnumValue(i2,_) -> i1 = i2
 		| EnumValue(i1,_),EnumValue(i2,_) -> i1 = i2
 		| _ -> false
 		| _ -> false
 
 
@@ -372,6 +374,7 @@ module ConstPropagation = DataFlow(struct
 		let rec eval bb e =
 		let rec eval bb e =
 			let wrap = function
 			let wrap = function
 				| Const ct -> mk (TConst ct) t_dynamic null_pos
 				| Const ct -> mk (TConst ct) t_dynamic null_pos
+				| Null t -> mk (TConst TNull) t e.epos
 				| _ -> raise Exit
 				| _ -> raise Exit
 			in
 			in
 			let unwrap e = match e.eexpr with
 			let unwrap e = match e.eexpr with
@@ -379,8 +382,10 @@ module ConstPropagation = DataFlow(struct
 				| _ -> raise Exit
 				| _ -> raise Exit
 			in
 			in
 			match e.eexpr with
 			match e.eexpr with
-			| TConst (TSuper | TThis | TNull) ->
+			| TConst (TSuper | TThis) ->
 				Bottom
 				Bottom
+			| TConst TNull ->
+				Null e.etype
 			| TConst ct ->
 			| TConst ct ->
 				Const ct
 				Const ct
 			| TLocal v ->
 			| TLocal v ->
@@ -465,7 +470,7 @@ module ConstPropagation = DataFlow(struct
 
 
 	let commit ctx =
 	let commit ctx =
 		let inline e i = match get_cell i with
 		let inline e i = match get_cell i with
-			| Top | Bottom | EnumValue _ ->
+			| Top | Bottom | EnumValue _ | Null _ ->
 				raise Not_found
 				raise Not_found
 			| Const ct ->
 			| Const ct ->
 				let e' = Codegen.type_constant ctx.com (tconst_to_const ct) e.epos in
 				let e' = Codegen.type_constant ctx.com (tconst_to_const ct) e.epos in