aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@mozilla.com>2011-02-22 20:49:21 -0800
committerAlon Zakai <azakai@mozilla.com>2011-02-22 20:49:21 -0800
commit8d224bc085bbfcf626db8fe1da2a9679d13d96f4 (patch)
treee707275bbff04c84e2560815988a7964976c7538 /src
parent9efae48667c05a5cd7e699a3a95b7db80539b801 (diff)
optimize type discovery
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js21
-rw-r--r--src/framework.js16
-rw-r--r--src/intertyper.js25
-rw-r--r--src/modules.js2
-rw-r--r--src/parseTools.js20
-rw-r--r--src/utility.js19
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);