From e814b40a7111c61220cdba6a95ab62b43a33bcba Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 30 May 2013 10:12:51 -0700 Subject: [PATCH] handle phi loops properly --- src/jsifier.js | 4 +- tests/cases/philoop.ll | 305 ++++++++++++++++++++++++++++++++++++++++ tests/cases/philoop.txt | 1 + 3 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 tests/cases/philoop.ll create mode 100644 tests/cases/philoop.txt diff --git a/src/jsifier.js b/src/jsifier.js index bcc179d7e..77aff895b 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1032,13 +1032,13 @@ function JSify(data, functionsOnly, givenFunctions) { } for (var i = 0; i < idents.length; i++) { if (keys(deps[idents[i]]).length == 0) { - pre = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + pre; + post = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + post; remove(idents[i]); continue mainLoop; } } // If we got here, we have circular dependencies, and must break at least one. - pre = 'var ' + idents[0] + '$phi = ' + valueJSes[idents[0]] + ';' + pre; + pre += 'var ' + idents[0] + '$phi = ' + valueJSes[idents[0]] + ';'; post += 'var ' + idents[0] + ' = ' + idents[0] + '$phi;'; remove(idents[0]); } diff --git a/tests/cases/philoop.ll b/tests/cases/philoop.ll new file mode 100644 index 000000000..5036c7baf --- /dev/null +++ b/tests/cases/philoop.ll @@ -0,0 +1,305 @@ +; ModuleID = '/tmp/tmpVIBz29/a.out.bc' +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" +target triple = "le32-unknown-nacl" + +@.str = private unnamed_addr constant [13 x i8] c"99\0A70\0A26\0A97\0A\00", align 1 +@.str1 = private unnamed_addr constant [12 x i8] c"%u %u %u %u\00", align 1 +@.str2 = private unnamed_addr constant [10 x i8] c"res = %u\0A\00", align 1 + +define i32 @main() nounwind { + %jp0 = alloca i32, align 4 + %i1 = alloca i32, align 4 + %jq3 = alloca i32, align 4 + %i = alloca i32, align 4 + %cq = alloca [100 x i32], align 4 + %ye = alloca [100 x i32], align 4 + %g = alloca [100 x i32], align 4 + %z = alloca [100 x i32], align 4 + %za = alloca [100 x [100 x i32]], align 4 + %a0 = alloca [100 x i32], align 4 + store i32 99, i32* %jp0, align 4 + store i32 70, i32* %i1, align 4 + store i32 26, i32* %jq3, align 4 + store i32 97, i32* %i, align 4 + br label %.lr.ph.i + +.lr.ph.i: ; preds = %.lr.ph.i, %0 + %j.07.i = phi i32 [ %7, %.lr.ph.i ], [ 0, %0 ] + %1 = and i32 %j.07.i, 1 + %2 = icmp eq i32 %1, 0 + %3 = sub i32 0, %j.07.i + %.p.i = select i1 %2, i32 %j.07.i, i32 %3 + %4 = add i32 %.p.i, 2 + %5 = urem i32 %4, 101 + %6 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 %j.07.i + store i32 %5, i32* %6, align 4 + %7 = add i32 %j.07.i, 1 + %8 = icmp ult i32 %7, 100 + br i1 %8, label %.lr.ph.i, label %.lr.ph.i44.preheader + +.lr.ph.i44.preheader: ; preds = %.lr.ph.i + %9 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 0 + br label %.lr.ph.i44 + +.lr.ph.i44: ; preds = %.lr.ph.i44, %.lr.ph.i44.preheader + %j.07.i42 = phi i32 [ %16, %.lr.ph.i44 ], [ 0, %.lr.ph.i44.preheader ] + %10 = and i32 %j.07.i42, 1 + %11 = icmp eq i32 %10, 0 + %12 = sub i32 0, %j.07.i42 + %.p.i43 = select i1 %11, i32 %j.07.i42, i32 %12 + %13 = add i32 %.p.i43, 90 + %14 = urem i32 %13, 101 + %15 = getelementptr inbounds [100 x i32]* %ye, i32 0, i32 %j.07.i42 + store i32 %14, i32* %15, align 4 + %16 = add i32 %j.07.i42, 1 + %17 = icmp ult i32 %16, 100 + br i1 %17, label %.lr.ph.i44, label %.lr.ph.i40 + +.lr.ph.i40: ; preds = %.lr.ph.i40, %.lr.ph.i44 + %j.07.i38 = phi i32 [ %24, %.lr.ph.i40 ], [ 0, %.lr.ph.i44 ] + %18 = and i32 %j.07.i38, 1 + %19 = icmp eq i32 %18, 0 + %20 = sub i32 0, %j.07.i38 + %.p.i39 = select i1 %19, i32 %j.07.i38, i32 %20 + %21 = add i32 %.p.i39, 73 + %22 = urem i32 %21, 101 + %23 = getelementptr inbounds [100 x i32]* %g, i32 0, i32 %j.07.i38 + store i32 %22, i32* %23, align 4 + %24 = add i32 %j.07.i38, 1 + %25 = icmp ult i32 %24, 100 + br i1 %25, label %.lr.ph.i40, label %.lr.ph.i36 + +.lr.ph.i36: ; preds = %.lr.ph.i36, %.lr.ph.i40 + %j.07.i34 = phi i32 [ %32, %.lr.ph.i36 ], [ 0, %.lr.ph.i40 ] + %26 = and i32 %j.07.i34, 1 + %27 = icmp eq i32 %26, 0 + %28 = sub i32 0, %j.07.i34 + %.p.i35 = select i1 %27, i32 %j.07.i34, i32 %28 + %29 = add i32 %.p.i35, 54 + %30 = urem i32 %29, 101 + %31 = getelementptr inbounds [100 x i32]* %z, i32 0, i32 %j.07.i34 + store i32 %30, i32* %31, align 4 + %32 = add i32 %j.07.i34, 1 + %33 = icmp ult i32 %32, 100 + br i1 %33, label %.lr.ph.i36, label %.lr.ph.i32 + +.lr.ph.i32: ; preds = %.lr.ph.i32, %.lr.ph.i36 + %j.07.i30 = phi i32 [ %40, %.lr.ph.i32 ], [ 0, %.lr.ph.i36 ] + %34 = and i32 %j.07.i30, 1 + %35 = icmp eq i32 %34, 0 + %36 = sub i32 0, %j.07.i30 + %.p.i31 = select i1 %35, i32 %j.07.i30, i32 %36 + %37 = add i32 %.p.i31, 66 + %38 = urem i32 %37, 101 + %39 = getelementptr inbounds [100 x [100 x i32]]* %za, i32 0, i32 0, i32 %j.07.i30 + store i32 %38, i32* %39, align 4 + %40 = add i32 %j.07.i30, 1 + %41 = icmp ult i32 %40, 10000 + br i1 %41, label %.lr.ph.i32, label %.lr.ph.i28 + +.lr.ph.i28: ; preds = %.lr.ph.i28, %.lr.ph.i32 + %j.07.i26 = phi i32 [ %48, %.lr.ph.i28 ], [ 0, %.lr.ph.i32 ] + %42 = and i32 %j.07.i26, 1 + %43 = icmp eq i32 %42, 0 + %44 = sub i32 0, %j.07.i26 + %.p.i27 = select i1 %43, i32 %j.07.i26, i32 %44 + %45 = add i32 %.p.i27, 71 + %46 = urem i32 %45, 101 + %47 = getelementptr inbounds [100 x i32]* %a0, i32 0, i32 %j.07.i26 + store i32 %46, i32* %47, align 4 + %48 = add i32 %j.07.i26, 1 + %49 = icmp ult i32 %48, 100 + br i1 %49, label %.lr.ph.i28, label %init.exit29 + +init.exit29: ; preds = %.lr.ph.i28 + %50 = call i32 (i8*, i8*, ...)* @sscanf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8]* @.str1, i32 0, i32 0), i32* %jp0, i32* %i1, i32* %jq3, i32* %i) nounwind + %51 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 46 + %52 = load i32* %51, align 4 + %53 = getelementptr inbounds [100 x i32]* %cq, i32 0, i32 20 + %54 = load i32* %53, align 4 + %55 = icmp ult i32 %52, %54 + br i1 %55, label %.preheader61, label %56 + +;