Compiler tuning
Significant reduction in memory usage by the compiler.
o Estimated sizes of growable lists to avoid waste
o Changed basic block predecessor structure from a growable bitmap
to a growable list.
o Conditionalized code which produced disassembly strings.
o Avoided generating some dataflow-related structures when compiling
in dataflow-disabled mode.
o Added memory usage statistics
o Eliminated floating point usage as a barrier to disabling expensive
dataflow analysis for very large init routines.
o Because iterating through sparse bit maps is much less of a concern now,
removed earlier hack that remembered runs of leading and trailing
zeroes.
Also, some general tuning.
o Minor tweaks to register utilties
o Speed up the assembly loop
o Rewrite of the bit vector iterator
Our previous worst-case method originally consumed 360 megabytes, but through
earlier changes was whittled down to 113 megabytes. Now it consumes 12 (which
so far appears to close to the highest compiler heap usage of anything
I've seen).
Post-wipe cold boot time is now less than 7 minutes.
Installation time for our application test cases also shows a large
gain - typically 25% to 40% speedup.
Single-threaded host compilation of core.jar down to <3.0s, boot.oat builds
in 17.2s. Next up: multi-threaded compilation.
Change-Id: I493d0d584c4145a6deccdd9bff344473023deb46
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 1eb6c64..b17855b 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -66,12 +66,10 @@
* benefit in optimizing these methods, and the cost can be very high.
* We attempt to identify these cases, and avoid performing most dataflow
* analysis. Two thresholds are used - one for known initializers and one
- * for everything else. Note: we require dataflow analysis for floating point
- * type inference. If any non-move fp operations exist in a method, dataflow
- * is performed regardless of block count.
+ * for everything else.
*/
-#define MANY_BLOCKS_INITIALIZER 200 /* Threshold for switching dataflow off */
-#define MANY_BLOCKS 3000 /* Non-initializer threshold */
+#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
+#define MANY_BLOCKS 4000 /* Non-initializer threshold */
typedef enum BBType {
kEntryBlock,
@@ -175,7 +173,7 @@
struct BasicBlock* taken;
struct BasicBlock* iDom; // Immediate dominator
struct BasicBlockDataFlow* dataFlowInfo;
- ArenaBitVector* predecessors;
+ GrowableList* predecessors;
ArenaBitVector* dominators;
ArenaBitVector* iDominated; // Set nodes being immediately dominated
ArenaBitVector* domFrontier; // Dominance frontier
@@ -328,13 +326,13 @@
GrowableList fillArrayData;
const u2* insns;
u4 insnsSize;
- bool usesFP; // Method contains at least 1 non-move FP operation
bool disableDataflow; // Skip dataflow analysis if possible
std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
+ int defCount; // Used to estimate number of SSA names
} CompilationUnit;
-BasicBlock* oatNewBB(BBType blockType, int blockId);
+BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
void oatAppendMIR(BasicBlock* bb, MIR* mir);