diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-02-22 20:49:21 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-02-22 20:49:21 -0800 |
commit | 8d224bc085bbfcf626db8fe1da2a9679d13d96f4 (patch) | |
tree | e707275bbff04c84e2560815988a7964976c7538 /src | |
parent | 9efae48667c05a5cd7e699a3a95b7db80539b801 (diff) |
optimize type discovery
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 21 | ||||
-rw-r--r-- | src/framework.js | 16 | ||||
-rw-r--r-- | src/intertyper.js | 25 | ||||
-rw-r--r-- | src/modules.js | 2 | ||||
-rw-r--r-- | src/parseTools.js | 20 | ||||
-rw-r--r-- | src/utility.js | 19 |
6 files changed, 51 insertions, 52 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index b5ab29d9..66013f26 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -134,22 +134,10 @@ function analyzer(data) { // Typevestigator substrate.addActor('Typevestigator', { processItem: function(data) { - // Find additional types - walkJSON(data, function(item) { - if (!item) return; - if (item.type) { - addType(item.type, data); - } - if (item.type2) { - addType(item.type2, data); - } - if (item.pointerType) { - addType(item.pointerType, data); - } - if (item.valueType) { - addType(item.valueType, data); - } - }); + for (type in Types.needAnalysis) { + if (type) addType(type, data); + } + Types.needAnalysis = []; this.forwardItem(data, 'Typeanalyzer'); } }); @@ -180,7 +168,6 @@ function analyzer(data) { if (type.flatIndexes) return; var ready = true; type.fields.forEach(function(field) { - //print('// zz getT: ' + type.name_ + ' : ' + field); if (isStructType(field)) { if (!Types.types[field]) { addType(field, item); diff --git a/src/framework.js b/src/framework.js index 7873353b..f5eb099d 100644 --- a/src/framework.js +++ b/src/framework.js @@ -155,16 +155,12 @@ Actor.prototype = { var ret = []; for (var i = 0; i < items.length; i++) { var item = items[i]; - try { - Framework.currItem = item; - var outputs = this.processItem(item); - Framework.currItem = null; // Do not keep an unneeded reference. Note that we don't care about this if an exception is thrown - if (outputs) { - ret = ret.concat(outputs); - } - } catch (e) { - print("Exception in process(), current item is: " + dump(item)); - throw e; + dprint('frameworkLines', 'Processing item for llvm line ' + item.lineNum); + Framework.currItem = item; + var outputs = this.processItem(item); + Framework.currItem = null; + if (outputs) { + ret = ret.concat(outputs); } } return ret; diff --git a/src/intertyper.js b/src/intertyper.js index 57e24eeb..6cb2a341 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -340,8 +340,8 @@ function intertyper(data, parseFunctions, baseLineNum) { } else { // variable var ident = item.tokens[0].text; - while (item.tokens[2].text in LLVM.LINKAGES || item.tokens[2].text in set('constant', 'global', 'hidden')) - item.tokens.splice(2, 1); + cleanOutTokensSet(LLVM.GLOBAL_MODIFIERS, item.tokens, 3); + cleanOutTokensSet(LLVM.GLOBAL_MODIFIERS, item.tokens, 2); var external = false; if (item.tokens[2].text === 'external') { external = true; @@ -354,6 +354,7 @@ function intertyper(data, parseFunctions, baseLineNum) { external: external, lineNum: item.lineNum }; + Types.needAnalysis[ret.type] = 0; if (ident == '@llvm.global_ctors') { ret.ctors = []; if (item.tokens[3].item) { @@ -449,6 +450,7 @@ function intertyper(data, parseFunctions, baseLineNum) { if (item.tokens[0].text == 'volatile') item.tokens.shift(0); item.pointerType = item.tokens[1].text; item.valueType = item.type = removePointing(item.pointerType); + Types.needAnalysis[item.type] = 0; if (item.tokens[2].text == 'getelementptr') { var last = getTokenIndexByText(item.tokens, ';'); var data = parseLLVMFunctionCall(item.tokens.slice(1, last)); @@ -476,6 +478,7 @@ function intertyper(data, parseFunctions, baseLineNum) { var last = getTokenIndexByText(item.tokens, ';'); item.intertype = 'extractvalue'; item.type = item.tokens[1].text; // Of the origin aggregate - not what we extract from it. For that, can only infer it later + Types.needAnalysis[item.type] = 0; item.ident = toNiceIdent(item.tokens[2].text); item.indexes = splitTokenList(item.tokens.slice(4, last)); this.forwardItem(item, 'Reintegrator'); @@ -486,8 +489,10 @@ function intertyper(data, parseFunctions, baseLineNum) { processItem: function(item) { item.intertype = 'bitcast'; item.type = item.tokens[1].text; + Types.needAnalysis[item.type] = 0; item.ident = toNiceIdent(item.tokens[2].text); item.type2 = item.tokens[4].text; + Types.needAnalysis[item.type2] = 0; this.forwardItem(item, 'Reintegrator'); } }); @@ -520,6 +525,7 @@ function intertyper(data, parseFunctions, baseLineNum) { item.tokens.splice(1, 1); } item.type = item.tokens[1].text; + Types.needAnalysis[item.type] = 0; item.functionType = ''; while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS)) { // We cannot compile assembly. If you hit this, perhaps tell the compiler not @@ -566,6 +572,7 @@ function intertyper(data, parseFunctions, baseLineNum) { } cleanOutTokens(['alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'], item.tokens, 4); item.type = item.tokens[1].text; + Types.needAnalysis[item.type] = 0; item.ident = toNiceIdent(item.tokens[2].text); item.params = parseParamTokens(item.tokens[3].item.tokens); item.toLabel = toNiceIdent(item.tokens[6].text); @@ -586,7 +593,9 @@ function intertyper(data, parseFunctions, baseLineNum) { item.allocatedType = item.tokens[1].text; item.allocatedNum = (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) ? toNiceIdent(item.tokens[4].text) : 1; item.type = addPointing(item.tokens[1].text); // type of pointer we will get + Types.needAnalysis[item.type] = 0; item.type2 = item.tokens[1].text; // value we will create, and get a pointer to + Types.needAnalysis[item.type2] = 0; this.forwardItem(item, 'Reintegrator'); } }); @@ -595,6 +604,7 @@ function intertyper(data, parseFunctions, baseLineNum) { processItem: function(item) { item.intertype = 'phi'; item.type = item.tokens[1].text; + Types.needAnalysis[item.type] = 0; var last = getTokenIndexByText(item.tokens, ';'); item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) { var subSegments = splitTokenList(segment[0].item.tokens); @@ -632,6 +642,7 @@ function intertyper(data, parseFunctions, baseLineNum) { } else { item.type = item.param1.type; } + Types.needAnalysis[item.type] = 0; this.forwardItem(item, 'Reintegrator'); } }); @@ -647,8 +658,10 @@ function intertyper(data, parseFunctions, baseLineNum) { pointer: parseLLVMSegment(segments[1]), lineNum: item.lineNum }; + Types.needAnalysis[ret.valueType] = 0; ret.ident = toNiceIdent(ret.pointer.ident); ret.pointerType = ret.pointer.type; + Types.needAnalysis[ret.pointerType] = 0; return [ret]; } }); @@ -675,9 +688,11 @@ function intertyper(data, parseFunctions, baseLineNum) { // 'ret' substrate.addActor('Return', { processItem: function(item) { + var type = item.tokens[1].text; + Types.needAnalysis[type] = 0; return [{ intertype: 'return', - type: item.tokens[1].text, + type: type, value: item.tokens[2] ? parseLLVMSegment(item.tokens.slice(2)) : null, lineNum: item.lineNum }]; @@ -698,9 +713,11 @@ function intertyper(data, parseFunctions, baseLineNum) { } return ret; } + var type = item.tokens[1].text; + Types.needAnalysis[type] = 0; return [{ intertype: 'switch', - type: item.tokens[1].text, + type: type, ident: toNiceIdent(item.tokens[2].text), defaultLabel: toNiceIdent(item.tokens[5].text), switchLabels: parseSwitchLabels(item.tokens[6]), diff --git a/src/modules.js b/src/modules.js index f2c458f5..ed3f1f23 100644 --- a/src/modules.js +++ b/src/modules.js @@ -8,6 +8,7 @@ var LLVM = { 'weak_odr', 'externally_visible', 'dllimport', 'dllexport'), CALLING_CONVENTIONS: set('ccc', 'fastcc', 'coldcc', 'cc10') }; +LLVM.GLOBAL_MODIFIERS = set(keys(LLVM.LINKAGES).concat(['constant', 'global', 'hidden'])); var Debugging = { processMetadata: function(lines) { @@ -96,5 +97,6 @@ var Debugging = { var Types = { types: {}, + needAnalysis: {} // Types noticed during parsing, that need analysis }; diff --git a/src/parseTools.js b/src/parseTools.js index 4c70867a..a6a1038b 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -271,6 +271,7 @@ function parseParamTokens(params) { value: null, ident: toNiceIdent('%') + anonymousIndex }); + Types.needAnalysis[ret.type] = 0; anonymousIndex ++; } } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { @@ -289,6 +290,7 @@ function parseParamTokens(params) { value: segment[1], ident: toNiceIdent(parseNumerical(segment[1].text)) }); + Types.needAnalysis[ret.type] = 0; // } else { // throw "what is this params token? " + JSON.stringify(segment); } @@ -298,23 +300,30 @@ function parseParamTokens(params) { // Segment ==> Parameter function parseLLVMSegment(segment) { + var type; if (segment.length == 1) { + type = isType(segment[0].text) ? segment[0].text : '?'; + Types.needAnalysis[type] = 0; return { intertype: 'value', ident: toNiceIdent(segment[0].text), - type: isType(segment[0].text) ? segment[0].text : '?' + type: type }; } else if (segment[1].type == '{') { + type = segment[0].text; + Types.needAnalysis[type] = 0; return { intertype: 'structvalue', values: splitTokenList(segment[1].tokens).map(parseLLVMSegment), - type: segment[0].text + type: type }; } else if (segment[0].text in PARSABLE_LLVM_FUNCTIONS) { return parseLLVMFunctionCall([{text: '?'}].concat(segment)); } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { return parseLLVMFunctionCall(segment); } else { + type = segment[0].text; + Types.needAnalysis[type] = 0; return { intertype: 'value', ident: toNiceIdent(segment[1].text), @@ -365,6 +374,7 @@ function parseLLVMFunctionCall(segment) { type: type, params: parseParamTokens(segment[2].item.tokens) }; + Types.needAnalysis[ret.type] = 0; ret.ident = toNiceIdent(ret.params[0].ident); return ret; } @@ -393,6 +403,12 @@ function cleanOutTokens(filterOut, tokens, index) { } } +function cleanOutTokensSet(filterOut, tokens, index) { + while (tokens[index].text in filterOut) { + tokens.splice(index, 1); + } +} + function _IntToHex(x) { assert(x >= 0 && x <= 15); if (x <= 9) { diff --git a/src/utility.js b/src/utility.js index fc5f7f88..f0d8e37e 100644 --- a/src/utility.js +++ b/src/utility.js @@ -91,25 +91,6 @@ function zeros(size) { return ret; } -function walkJSON(item, func) { - if (item.length) { - for (var x = 0; x < item.length; x++) { - var y = item[x]; - if (y && typeof y === 'object') { - walkJSON(y, func); - } - } - } else { - func(item); - for (x in item) { - var y = item[x]; - if (y && typeof y === 'object') { - walkJSON(y, func); - } - } - } -} - function keys(x) { var ret = []; for (a in x) ret.push(a); |