aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-03 21:22:03 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-03 21:22:03 -0800
commit122b5bba34dd024a54b790caf5aabeec42a779d3 (patch)
tree9b2d6419684f23fc07f8944e591c78d0579f8291 /src
parent556decb19a4bcb32daad1569402fcc385d49b1d4 (diff)
various minor compiler optimizations
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js7
-rw-r--r--src/intertyper.js29
-rw-r--r--src/jsifier.js11
-rw-r--r--src/modules.js1
-rw-r--r--src/parseTools.js23
5 files changed, 48 insertions, 23 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 5b34c665..677b61b0 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -15,6 +15,12 @@ function cleanFunc(func) {
});
}
+// Handy sets
+
+var BRANCH_INVOKE = set('branch', 'invoke');
+
+// Analyzer
+
function analyzer(data) {
// Substrate
var substrate = new Substrate('Analyzer');
@@ -728,7 +734,6 @@ function analyzer(data) {
}
});
- var BRANCH_INVOKE = set('branch', 'invoke');
function operateOnLabels(line, func) {
function process(item, id) {
['label', 'labelTrue', 'labelFalse', 'toLabel', 'unwindLabel', 'defaultLabel'].forEach(function(id) {
diff --git a/src/intertyper.js b/src/intertyper.js
index 834345bf..03fbf072 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -9,6 +9,20 @@ function tokenize(text) {
return tokenizer.processItem({ lineText: text }, true);
}
+// Handy sets
+
+var ENCLOSER_STARTERS = set('[', '(', '<');
+var ENCLOSER_ENDERS = {
+ '[': ']',
+ '(': ')',
+ '<': '>'
+};
+var MATHOPS = set(['add', 'sub', 'sdiv', 'udiv', 'mul', 'icmp', 'zext', 'urem', 'srem', 'fadd', 'fsub', 'fmul', 'fdiv', 'fcmp', 'uitofp', 'sitofp', 'fpext', 'fptrunc', 'fptoui', 'fptosi', 'trunc', 'sext', 'select', 'shl', 'shr', 'ashl', 'ashr', 'lshr', 'lshl', 'xor', 'or', 'and', 'ptrtoint', 'inttoptr']);
+var ZEROINIT_UNDEF = set('zeroinitializer', 'undef');
+var NSW_NUW = set('nsw', 'nuw');
+
+// Intertyper
+
function intertyper(data, sidePass, baseLineNum) {
var mainPass = !sidePass;
baseLineNum = baseLineNum || 0;
@@ -124,13 +138,6 @@ function intertyper(data, sidePass, baseLineNum) {
}
});
- var ENCLOSER_STARTERS = set('[', '(', '<');
- var ENCLOSER_ENDERS = {
- '[': ']',
- '(': ')',
- '<': '>'
- };
-
// Line tokenizer
tokenizer = substrate.addActor('Tokenizer', {
processItem: function _tokenizer(item, inner) {
@@ -280,8 +287,6 @@ function intertyper(data, sidePass, baseLineNum) {
}
});
- var MATHOPS = set(['add', 'sub', 'sdiv', 'udiv', 'mul', 'icmp', 'zext', 'urem', 'srem', 'fadd', 'fsub', 'fmul', 'fdiv', 'fcmp', 'uitofp', 'sitofp', 'fpext', 'fptrunc', 'fptoui', 'fptosi', 'trunc', 'sext', 'select', 'shl', 'shr', 'ashl', 'ashr', 'lshr', 'lshl', 'xor', 'or', 'and', 'ptrtoint', 'inttoptr']);
-
substrate.addActor('Triager', {
processItem: function _triager(item) {
function triage() {
@@ -407,7 +412,7 @@ function intertyper(data, sidePass, baseLineNum) {
Types.needAnalysis[type] = 0;
if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) {
return { value: toNiceIdent(value.text), type: type };
- } else if (value.text in set('zeroinitializer', 'undef')) { // undef doesn't really need initting, but why not
+ } else if (value.text in ZEROINIT_UNDEF) { // undef doesn't really need initting, but why not
return { intertype: 'emptystruct', type: type };
} else if (value.text && value.text[0] == '"') {
return { intertype: 'string', text: value.text.substr(1, value.text.length-2) };
@@ -519,7 +524,7 @@ function intertyper(data, sidePass, baseLineNum) {
var funcHeader = substrate.addActor('FuncHeader', {
processItem: function(item) {
item.tokens = item.tokens.filter(function(token) {
- return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in set('hidden', 'nounwind', 'define', 'inlinehint', '{') || token.text in LLVM.CALLING_CONVENTIONS);
+ return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in LLVM.FUNC_ATTR || token.text in LLVM.CALLING_CONVENTIONS);
});
var params = parseParamTokens(item.tokens[2].item.tokens);
return [{
@@ -776,7 +781,7 @@ function intertyper(data, sidePass, baseLineNum) {
item.intertype = 'mathop';
item.op = item.tokens[0].text;
item.variant = null;
- while (item.tokens[1].text in set('nsw', 'nuw')) item.tokens.splice(1, 1);
+ while (item.tokens[1].text in NSW_NUW) item.tokens.splice(1, 1);
if (['icmp', 'fcmp'].indexOf(item.op) != -1) {
item.variant = item.tokens[1].text;
item.tokens.splice(1, 1);
diff --git a/src/jsifier.js b/src/jsifier.js
index 2cb4dee9..df2ae43f 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -3,7 +3,12 @@
// Convert analyzed data to javascript. Everything has already been calculated
// before this stage, which just does the final conversion to JavaScript.
-// Main function
+// Handy sets
+
+var STRUCT_LIST = set('struct', 'list');
+var UNDERSCORE_OPENPARENS = set('_', '(');
+
+// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -195,7 +200,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret = makeEmptyStruct(segment.type);
} else if (segment.intertype in PARSABLE_LLVM_FUNCTIONS) {
ret = finalizeLLVMFunctionCall(segment);
- } else if (segment.intertype in set('struct', 'list')) {
+ } else if (segment.intertype in STRUCT_LIST) {
ret = alignStruct(handleSegments(segment.contents), segment.type);
} else if (segment.intertype === 'string') {
ret = parseLLVMString(segment.text); // + ' /* ' + text + '*/';
@@ -237,7 +242,7 @@ function JSify(data, functionsOnly, givenFunctions) {
substrate.addActor('GlobalVariable', {
processItem: function(item) {
function needsPostSet(value) {
- return value[0] in set('_', '(') || value.substr(0, 14) === 'CHECK_OVERFLOW';
+ return value[0] in UNDERSCORE_OPENPARENS || value.substr(0, 14) === 'CHECK_OVERFLOW';
}
item.intertype = 'GlobalVariableStub';
diff --git a/src/modules.js b/src/modules.js
index 411bc66f..3ce4a541 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -10,6 +10,7 @@ var LLVM = {
'weak_odr', 'externally_visible', 'dllimport', 'dllexport', 'unnamed_addr'),
VISIBILITIES: set('default', 'hidden', 'protected'),
PARAM_ATTR: set('noalias', 'signext', 'zeroext', 'inreg', 'sret', 'nocapture', 'nest'),
+ FUNC_ATTR: set('hidden', 'nounwind', 'define', 'inlinehint', '{'),
CALLING_CONVENTIONS: set('ccc', 'fastcc', 'coldcc', 'cc10', 'x86_fastcallcc', 'x86_stdcallcc'),
ACCESS_OPTIONS: set('volatile', 'atomic'),
INVOKE_MODIFIERS: set('alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'),
diff --git a/src/parseTools.js b/src/parseTools.js
index 800d6b8b..3eaf3577 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -225,6 +225,8 @@ function findTokenText(item, text) {
return -1;
}
+var SPLIT_TOKEN_LIST_SPLITTERS = set(',', 'to'); // 'to' can separate parameters as well...
+
// Splits a list of tokens separated by commas. For example, a list of arguments in a function call
function splitTokenList(tokens) {
if (tokens.length == 0) return [];
@@ -232,10 +234,9 @@ function splitTokenList(tokens) {
if (tokens.slice(-1)[0].text != ',') tokens.push({text:','});
var ret = [];
var seg = [];
- var SPLITTERS = set(',', 'to'); // 'to' can separate parameters as well...
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
- if (token.text in SPLITTERS) {
+ if (token.text in SPLIT_TOKEN_LIST_SPLITTERS) {
ret.push(seg);
seg = [];
} else if (token.text == ';') {
@@ -1013,12 +1014,14 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align) {
var UNROLL_LOOP_MAX = 5;
+var ZERO_ONE = set(0, 1);
+
function makeSetValues(ptr, pos, value, type, num) {
function safety(where) {
where = where || getFastValue(ptr, '+', pos) + '+mspi';
return ';' + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + where + ', ' + type + ', 1)' : '');
}
- if (USE_TYPED_ARRAYS in set(0, 1)) {
+ if (USE_TYPED_ARRAYS in ZERO_ONE) {
if (isNumber(num)) {
if (parseInt(num) <= UNROLL_LOOP_MAX) {
return range(num).map(function(i) {
@@ -1134,6 +1137,10 @@ function makeCopyValues(dest, src, num, type, modifier) {
return null;
}
+var PLUS_MUL = set('+', '*');
+var MUL_DIV = set('*', '/');
+var PLUS_MINUS = set('+', '-');
+
// Given two values and an operation, returns the result of that operation.
// Tries to do as much as possible at compile time.
function getFastValue(a, op, b, type) {
@@ -1142,12 +1149,12 @@ function getFastValue(a, op, b, type) {
if (isNumber(a) && isNumber(b)) {
return eval(a + op + b).toString();
}
- if (op in set('+', '*') && isNumber(a)) { // if one of them is a number, keep it last
+ if (op in PLUS_MUL && isNumber(a)) { // if one of them is a number, keep it last
var c = b;
b = a;
a = c;
}
- if (op in set('*', '/')) {
+ if (op in MUL_DIV) {
if (op == '*') {
if (a == 0 || b == 0) {
return '0';
@@ -1168,7 +1175,7 @@ function getFastValue(a, op, b, type) {
return a;
} // Doing shifts for division is problematic, as getting the rounding right on negatives is tricky
}
- } else if (op in set('+', '-')) {
+ } else if (op in PLUS_MINUS) {
if (b[0] == '-') {
op = op == '+' ? '-' : '+';
b = b.substr(1);
@@ -1212,9 +1219,11 @@ function makeGetPos(ptr) {
return ptr;
}
+var IHEAP_FHEAP = set('IHEAP', 'FHEAP');
+
function makePointer(slab, pos, allocator, type) {
assert(type, 'makePointer requires type info');
- if (slab.substr(0, 4) === 'HEAP' || (USE_TYPED_ARRAYS == 1 && slab in set('IHEAP', 'FHEAP'))) return pos;
+ if (slab.substr(0, 4) === 'HEAP' || (USE_TYPED_ARRAYS == 1 && slab in IHEAP_FHEAP)) return pos;
var types = generateStructTypes(type);
// compress type info and data if possible
var de;