aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-10-11 21:10:02 -0700
committeralon@honor <none@none>2010-10-11 21:10:02 -0700
commitcb9319ec92505750d2e1a17dd230141aba9edcf7 (patch)
treebe0af9b260a5ba9fa894a5be1fbd6110b31bd977
parent425295d786880c7741a9eab9768d5aa32a7c3faf (diff)
increment stack all at once; 2% speedup
-rw-r--r--src/analyzer.js29
-rw-r--r--src/jsifier.js16
-rw-r--r--src/parseTools.js8
-rw-r--r--src/runtime.js8
4 files changed, 48 insertions, 13 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index ce4a99af..2418170c 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -300,7 +300,34 @@ function analyzer(data) {
});
});
});
- this.forwardItem(item, 'Relooper');
+ this.forwardItem(item, 'StackAnalyzer');
+ },
+ });
+
+ // Stack analyzer - calculate the base stack usage
+ substrate.addZyme('StackAnalyzer', {
+ processItem: function(data) {
+ data.functions.forEach(function(func) {
+ var total = 0;
+ var lines = func.labels[0].lines;
+ for (var i = 0; i < lines.length; i++) {
+ var item = lines[i].value;
+ if (!item || item.intertype != 'alloca') break;
+ // FIXME: This ignores nativized variables, but probably negligible
+ item.allocatedSize = calcAllocatedSize(item.allocatedType, data.types);
+ total += item.allocatedSize;
+ }
+ func.initialStack = total;
+ var index = 0;
+ for (var i = 0; i < lines.length; i++) {
+ var item = lines[i].value;
+ if (!item || item.intertype != 'alloca') break;
+ index += item.allocatedSize;
+ item.allocatedIndex = index;
+ delete item.allocatedSize;
+ }
+ });
+ this.forwardItem(data, 'Relooper');
},
});
diff --git a/src/jsifier.js b/src/jsifier.js
index 547bde72..955fa900 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -276,7 +276,9 @@ function JSify(data) {
}).filter(function(param) { return param != null });;
func.JS = '\nfunction ' + func.ident + '(' + params.join(', ') + ') {\n';
- func.JS += ' ' + RuntimeGenerator.stackEnter() + '\n';
+
+ func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack) + ';\n';
+
if (LABEL_DEBUG) func.JS += " print(INDENT + ' Entering: " + func.ident + "'); INDENT += ' ';\n";
if (true) { // TODO: optimize away when not needed
@@ -591,15 +593,10 @@ function JSify(data) {
return item.ident + '.f' + item.indexes[0][0].text;
});
makeFuncLineZyme('alloca', function(item) {
- dprint('alloca', dump(item));
- if (pointingLevels(item.allocatedType) == 0 && isStructType(item.allocatedType)) {
- return RuntimeGenerator.stackAlloc(makeEmptyStruct(item.allocatedType).length);
- } else {
- return RuntimeGenerator.stackAlloc(1);
- }
+ assert(typeof item.allocatedIndex === 'number'); // or, return RuntimeGenerator.stackAlloc(calcAllocatedSize(item.allocatedType, TYPES));
+ return getFastValue('STACKTOP', '-', item.allocatedIndex.toString());
});
makeFuncLineZyme('phi', function(item) {
- dprint('phi', dump(item));
return '__lastLabel__ == ' + getLabelId(item.label1) + ' ? ' + toNiceIdent(item.value1) + ' : ' + toNiceIdent(item.value2);
});
@@ -612,7 +609,6 @@ function JSify(data) {
}
makeFuncLineZyme('mathop', function(item) { with(item) {
- dprint('mathop', 'mathop: ' + dump(item));
for (var i = 1; i <= 4; i++) {
if (item['param'+i]) {
item['ident'+i] = finalizeLLVMParameter(item['param'+i]);
@@ -705,7 +701,7 @@ function JSify(data) {
} else if (b == 1) {
return a;
}
- } else if (op == '+') {
+ } else if (op in set('+', '-')) {
if (!a) a = 0;
if (!b) b = 0;
if (a == 0) {
diff --git a/src/parseTools.js b/src/parseTools.js
index 4d1ed438..ca96ba65 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -446,3 +446,11 @@ function cleanLabel(label) {
}
}
+function calcAllocatedSize(type, TYPES) {
+ if (pointingLevels(type) == 0 && isStructType(type)) {
+ return TYPES[type].flatSize; // makeEmptyStruct(item.allocatedType).length;
+ } else {
+ return 1;
+ }
+}
+
diff --git a/src/runtime.js b/src/runtime.js
index 346020b0..0ae70fa3 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -25,8 +25,12 @@ RuntimeGenerator = {
return ret;
},
- stackEnter: function() {
- return 'STACK_STACK.push(STACKTOP);';
+ stackEnter: function(initial) {
+ var ret = 'STACK_STACK.push(STACKTOP); STACKTOP += ' + initial;
+ if (GUARD_MEMORY) {
+ ret += '; assert(STACKTOP < STACK_MAX)';
+ }
+ return ret;
},
stackExit: function() {