瀏覽代碼

fixed if/else support in GLSL

Nicolas Cannasse 9 年之前
父節點
當前提交
634e1ea0df
共有 3 個文件被更改,包括 42 次插入10 次删除
  1. 30 0
      hxsl/Ast.hx
  2. 11 10
      hxsl/Dce.hx
  3. 1 0
      hxsl/GlslOut.hx

+ 30 - 0
hxsl/Ast.hx

@@ -359,6 +359,36 @@ class Tools {
 		};
 	}
 
+	public static function hasSideEffect( e : TExpr ) {
+		switch( e.e ) {
+		case TParenthesis(e):
+			return hasSideEffect(e);
+		case TBlock(el), TArrayDecl(el):
+			for( e in el )
+				if( hasSideEffect(e) )
+					return true;
+			return false;
+		case TBinop(OpAssign | OpAssignOp(_), _, _):
+			return true;
+		case TBinop(_, e1, e2):
+			return hasSideEffect(e1) || hasSideEffect(e2);
+		case TUnop(_, e1):
+			return hasSideEffect(e1);
+		case TSwiz(e, _):
+			return hasSideEffect(e);
+		case TIf(econd, eif, eelse):
+			return hasSideEffect(econd) || hasSideEffect(eif) || (eelse != null && hasSideEffect(eelse));
+		case TFor(_, it, loop):
+			return hasSideEffect(it) || hasSideEffect(loop);
+		case TArray(e, index):
+			return hasSideEffect(e) || hasSideEffect(index);
+		case TConst(_), TVar(_), TGlobal(_):
+			return false;
+		case TVarDecl(_), TCall(_), TDiscard, TContinue, TBreak, TReturn(_):
+			return true;
+		}
+	}
+
 	public static function iter( e : TExpr, f : TExpr -> Void ) {
 		switch( e.e ) {
 		case TParenthesis(e): f(e);

+ 11 - 10
hxsl/Dce.hx

@@ -63,9 +63,9 @@ class Dce {
 		}
 
 		for( f in vertex.funs )
-			f.expr = mapExpr(f.expr);
+			f.expr = mapExpr(f.expr, false);
 		for( f in fragment.funs )
-			f.expr = mapExpr(f.expr);
+			f.expr = mapExpr(f.expr, false);
 
 
 		return {
@@ -142,26 +142,27 @@ class Dce {
 		}
 	}
 
-	function mapExpr( e : TExpr ) : TExpr {
+	function mapExpr( e : TExpr, isVar ) : TExpr {
 		switch( e.e ) {
 		case TBlock(el):
 			var out = [];
 			var count = 0;
 			for( e in el ) {
-				var e = mapExpr(e);
-				switch( e.e ) {
-				case TConst(_) if( count < el.length ):
-				case TBlock([]):
-				default:
+				var e = mapExpr(e, isVar);
+				if( e.hasSideEffect() || (isVar && count == el.length - 1) )
 					out.push(e);
-				}
 				count++;
 			}
 			return { e : TBlock(out), p : e.p, t : e.t };
 		case TVarDecl(v,_) | TBinop(OpAssign | OpAssignOp(_), { e : (TVar(v) | TSwiz( { e : TVar(v) }, _)) }, _) if( !get(v).used ):
 			return { e : TConst(CNull), t : e.t, p : e.p };
+		case TIf(e, econd, eelse):
+			var e = mapExpr(e, true);
+			var econd = mapExpr(econd, isVar);
+			var eelse = eelse == null ? null : mapExpr(eelse, isVar);
+			return { e : TIf(e, econd, eelse), p : e.p, t : e.t };
 		default:
-			return e.map(mapExpr);
+			return e.map(function(e) return mapExpr(e,true));
 		}
 	}
 

+ 1 - 0
hxsl/GlslOut.hx

@@ -341,6 +341,7 @@ class GlslOut {
 			add(") ");
 			addExpr(eif, tabs);
 			if( eelse != null ) {
+				if( !eif.e.match(TBlock(_)) ) add(";");
 				add(" else ");
 				addExpr(eelse, tabs);
 			}