aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-01-31 15:31:23 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-01-31 15:31:23 -0800
commita47bd793f2b73a75eb0baeec8741e1d3282c14de (patch)
tree427e427b62e3f36b10e560cd6a79b0c8180aba4d
parent350c10bc7dda90980965f1ce2e5b60ef85ad1a57 (diff)
unfolding in legalizer for load and store
-rw-r--r--src/analyzer.js27
-rw-r--r--tests/cases/legalizer_ta2.ll9
-rw-r--r--tests/cases/legalizer_ta2.txt1
3 files changed, 33 insertions, 4 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 2c42fa43..a4e7d52d 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -153,6 +153,24 @@ function analyzer(data, sidePass) {
}
return ret;
}
+ // Unfolds internal inline llvmfunc calls, for example x = load (bitcast y)
+ // will become temp = y \n x = load temp
+ // @return The index of the original line, after the unfolding. In the example
+ // above, the index returned will be the new index of the line with `load',
+ // that is, i+1.
+ function unfold(lines, i, item, slot) {
+ if (item[slot].intertype == 'value') return i;
+ // TODO: unfold multiple slots at once
+ var tempIdent = '$$emscripten$temp$' + i;
+ lines.splice(i, 0, {
+ intertype: 'assign',
+ ident: tempIdent,
+ value: item[slot],
+ lineNum: lines[i].lineNum - 0.5
+ });
+ item[slot] = { intertype: 'value', ident: tempIdent, type: item[slot].type };
+ return i+1;
+ }
data.functions.forEach(function(func) {
func.labels.forEach(function(label) {
var i = 0, bits;
@@ -161,11 +179,11 @@ function analyzer(data, sidePass) {
if (item.intertype == 'store') {
if (isIllegalType(item.valueType)) {
dprint('legalizer', 'Legalizing store at line ' + item.lineNum);
+ i = unfold(label.lines, i, item, 'value');
+ label.lines.splice(i, 1);
bits = getBits(item.valueType);
- assert(item.value.intertype == 'value', 'TODO: unfolding');
var elements;
elements = getLegalVars(item.value.ident, bits);
- label.lines.splice(i, 1);
var j = 0;
elements.forEach(function(element) {
var tempVar = '$st$' + i + '$' + j;
@@ -207,10 +225,11 @@ function analyzer(data, sidePass) {
case 'load': {
if (isIllegalType(value.valueType)) {
dprint('legalizer', 'Legalizing load at line ' + item.lineNum);
+ i = unfold(label.lines, i, value, 'pointer');
+ label.lines.splice(i, 1);
bits = getBits(value.valueType);
- assert(value.pointer.intertype == 'value', 'TODO: unfolding');
+// assert(value.pointer.intertype == 'value', 'TODO: unfolding');
var elements = getLegalVars(item.ident, bits);
- label.lines.splice(i, 1);
var j = 0;
elements.forEach(function(element) {
var tempVar = '$st$' + i + '$' + j;
diff --git a/tests/cases/legalizer_ta2.ll b/tests/cases/legalizer_ta2.ll
index cde3ec10..a877c683 100644
--- a/tests/cases/legalizer_ta2.ll
+++ b/tests/cases/legalizer_ta2.ll
@@ -2,6 +2,8 @@
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"
+@globaliz = global [300 x i8] zeroinitializer
+
define i32 @main() {
entry:
%buffer = alloca i8, i32 1000, align 4
@@ -92,6 +94,13 @@ entry:
store i104 %xored, i104* %bundled, align 4
call i32 (i8*)* @puts(i8* %buffer)
+; unfolding
+ store i104 %loaded, i104* bitcast ([300 x i8]* @globaliz to i104*), align 4
+ %loaded.short = load i80* bitcast ([300 x i8]* @globaliz to i80*), align 4
+ store i104 0, i104* bitcast ([300 x i8]* @globaliz to i104*), align 4
+ store i80 %loaded.short, i80* bitcast ([300 x i8]* @globaliz to i80*), align 4
+ call i32 (i8*)* @puts(i8* bitcast ([300 x i8]* @globaliz to i8*))
+
ret i32 1
}
diff --git a/tests/cases/legalizer_ta2.txt b/tests/cases/legalizer_ta2.txt
index 66fb8c59..e05a4816 100644
--- a/tests/cases/legalizer_ta2.txt
+++ b/tests/cases/legalizer_ta2.txt
@@ -14,3 +14,4 @@ gfedgfed
hellon worod
hello, war`d
hello, wor-d
+hello, wor