From: <cap...@us...> - 2008-09-03 20:40:59
|
Revision: 14951 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14951&view=rev Author: captain5050 Date: 2008-09-03 20:40:52 +0000 (Wed, 03 Sep 2008) Log Message: ----------- Add opt compiler option to print GC maps. A few other tidy ups. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/liveness/LiveAnalysis.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/liveness/LiveAnalysis.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/liveness/LiveAnalysis.java 2008-09-03 20:38:15 UTC (rev 14950) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/liveness/LiveAnalysis.java 2008-09-03 20:40:52 UTC (rev 14951) @@ -106,18 +106,11 @@ */ private ArrayList<LiveIntervalElement>[] registerMap; - // Debugging information - // Live Intervals, GC Maps, and fixed-point results - private static final boolean dumpFinalLiveIntervals = false; - private static final boolean dumpFinalMaps = false; - private static final boolean dumpFixedPointResults = false; - - // used for debugging. make it nonfinal to accept the argument from the input + /** Debugging info */ private static final boolean debug = false; - // even more debugging info + /** Even more debugging info */ private static final boolean verbose = false; - // End debugging information public String getName() { return "Live Analysis"; @@ -196,9 +189,19 @@ */ public void perform(IR ir) { + // Debugging information + // Live Intervals, GC Maps, and fixed-point results + final boolean dumpFinalLiveIntervals = debug || + ir.options.PRINT_GC_MAPS && + (!ir.options.hasMETHOD_TO_PRINT() || + (ir.options.hasMETHOD_TO_PRINT() && ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) + ); + final boolean dumpFinalMaps = dumpFinalLiveIntervals; + final boolean dumpFixedPointResults = dumpFinalLiveIntervals; + // make sure IR info is up-to-date DefUse.recomputeSpansBasicBlock(ir); - debugBegining(ir, createGCMaps); + debugBegining(ir, createGCMaps, dumpFinalLiveIntervals, dumpFinalMaps, dumpFixedPointResults); bbLiveInfo = new BBLiveElement[ir.cfg.numberOfNodes()]; for (int i = 0; i < ir.cfg.numberOfNodes(); i++) { @@ -222,7 +225,7 @@ // currentBlock is the first node in the list BasicBlock currentBlock = (BasicBlock) ir.cfg.buildRevTopSort(); - // 2nd parm: true means forward analysis; false means backward analysis + // 2nd param: true means forward analysis; false means backward analysis SortedGraphIterator bbIter = new SortedGraphIterator(currentBlock, false); while (currentBlock != null) { boolean changed = processBlock(currentBlock, reuseCurrentSet, ir); @@ -235,7 +238,7 @@ reuseCurrentSet = nextBlock != null && bbIter.isSinglePredecessor(currentBlock, nextBlock); currentBlock = nextBlock; } - debugPostGlobal(ir); + debugPostGlobal(ir, dumpFinalLiveIntervals, dumpFinalMaps, dumpFixedPointResults); // Now compute live ranges, using results from the fixed point computation // Also, optionally create GC maps @@ -911,9 +914,12 @@ * that is performed at the beginning of the perform method * @param ir the IR * @param createGCMaps are we creating GC maps? + * @param dumpFixedPointResults debug info + * @param dumpFinalMaps debug info + * @param dumpFinalLiveIntervals debug info */ - private void debugBegining(IR ir, boolean createGCMaps) { - if (debug || dumpFixedPointResults || dumpFinalMaps || dumpFinalLiveIntervals) { + private void debugBegining(IR ir, boolean createGCMaps, boolean dumpFixedPointResults, boolean dumpFinalMaps, boolean dumpFinalLiveIntervals) { + if (dumpFixedPointResults || dumpFinalMaps || dumpFinalLiveIntervals) { System.out.print("\n ====> Performing liveness analysis "); if (createGCMaps) { System.out.print("and GC Maps "); @@ -921,7 +927,7 @@ System.out.println("for method: " + ir.method.getName() + " in class: " + ir.method.getDeclaringClass() + "\n"); System.out.println(" method has " + ir.cfg.numberOfNodes() + " basic blocks"); } - if (debug || dumpFinalMaps) { + if (dumpFinalMaps) { System.out.println("**** START OF IR for method: " + ir.method.getName() + " in class: " + @@ -936,16 +942,17 @@ * that is performed after the global propagation step of "perform" * * @param ir the IR + * @param dumpFixedPointResults debug info + * @param dumpFinalMaps debug info + * @param dumpFinalLiveIntervals debug info */ - private void debugPostGlobal(IR ir) { + private void debugPostGlobal(IR ir, boolean dumpFixedPointResults, boolean dumpFinalMaps, boolean dumpFinalLiveIntervals) { if (debug) { System.out.println(" .... Completed global live computation ...."); if (verbose) { // Print the basic blocks System.out.println(" .... CFG:"); System.out.println(ir.cfg); - // Print the results for basic blocks - printFixedPointResults(ir); } } if (dumpFixedPointResults) { @@ -984,16 +991,6 @@ } /** - * Dumps the GC map, see printFinalMaps - */ - public void dumpMap() { - if (VM.VerifyAssertions) { - VM._assert(map != null); - } - map.dump(); - } - - /** * Prints the Final Live Intervals * @param ir the IR */ @@ -1063,7 +1060,7 @@ private LiveSet gen; private LiveSet BBKillSet; private LiveSet firstPEIKillSet; - private LiveSet in; + private final LiveSet in; private boolean containsPEIWithHandler = false; /** @@ -1130,20 +1127,6 @@ } /** - * DEPRECIATED: Don't Use - */ - public LiveSet gen() { - return gen; - } - - /** - * DEPRECIATED: Don't Use - */ - public LiveSet in() { - return in; - } - - /** * creates a string representation of this object * @return string representation of this object */ @@ -1163,6 +1146,9 @@ */ static final class MapElement { + private final Instruction inst; + private final List<RegSpillListElement> list; + /** * constructor * @param inst @@ -1188,9 +1174,6 @@ public List<RegSpillListElement> getList() { return list; } - - private Instruction inst; - private List<RegSpillListElement> list; } /* collect osr info according to live information */ Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java 2008-09-03 20:38:15 UTC (rev 14950) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptMachineCodeMap.java 2008-09-03 20:40:52 UTC (rev 14951) @@ -31,7 +31,7 @@ import org.jikesrvm.compilers.opt.ir.IR; import org.jikesrvm.compilers.opt.ir.Instruction; import org.jikesrvm.compilers.opt.ir.operand.MethodOperand; -import org.vmmagic.pragma.Interruptible; +import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Offset; @@ -65,7 +65,6 @@ * 1) methods called during compilation to create the maps * 2) methods called at GC time (no allocation allowed!) */ -@Uninterruptible public final class OptMachineCodeMap implements Constants, OptConstants { /** @@ -91,24 +90,31 @@ * @param ir the ir object for this method * @param machineCodeSize the number of machine code instructions generated. */ - @Interruptible static OptMachineCodeMap create(IR ir, int machineCodeSize) { + /** Dump maps as methods are compiled */ + final boolean DUMP_MAPS = + ir.options.PRINT_GC_MAPS && + (!ir.options.hasMETHOD_TO_PRINT() || + (ir.options.hasMETHOD_TO_PRINT() && ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) + ); + /** Dump stats on map size as maps are compiled */ + final boolean DUMP_MAP_SIZES = false; if (DUMP_MAPS) { VM.sysWrite("Creating final machine code map for " + ir.method + "\n"); } // create all machine code maps - final OptMachineCodeMap map = generateMCInformation(ir.MIRInfo.gcIRMap); + final OptMachineCodeMap map = generateMCInformation(ir.MIRInfo.gcIRMap, DUMP_MAPS); if (DUMP_MAP_SIZES) { map.recordStats(ir.method, map.size(), - machineCodeSize << ArchitectureSpecific.RegisterConstants.LG_INSTRUCTION_WIDTH); + machineCodeSize << ArchitectureSpecific.RegisterConstants.LG_INSTRUCTION_WIDTH, DUMP_MAP_SIZES); } if (DUMP_MAPS) { VM.sysWrite("Final Machine code information:\n"); - map.dumpMCInformation(); + map.dumpMCInformation(DUMP_MAPS); for (Instruction i = ir.firstInstructionInCodeOrder(); i != null; i = i.nextInstructionInCodeOrder()) { VM.sysWriteln(i.getmcOffset() + "\t" + i); } @@ -122,6 +128,7 @@ * @param MCOffset the machine code offset of interest * @return -1 if unknown. */ + @Uninterruptible public int getBytecodeIndexForMCOffset(Offset MCOffset) { int entry = findMCEntry(MCOffset); if (entry == -1) { @@ -137,6 +144,7 @@ * @param MCOffset the machine code offset of interest * @return null if unknown */ + @Uninterruptible public NormalMethod getMethodForMCOffset(Offset MCOffset) { int entry = findMCEntry(MCOffset); if (entry == -1) { @@ -156,6 +164,7 @@ * @param MCOffset the machine code offset of interest * @return -1 if unknown. */ + @Uninterruptible public int getInlineEncodingForMCOffset(Offset MCOffset) { int entry = findMCEntry(MCOffset); if (entry == -1) { @@ -173,6 +182,7 @@ * @param MCOffset the machine code offset to look for * @return the GC map index or OptGCMap.ERROR */ + @Uninterruptible public int findGCMapIndex(Offset MCOffset) { int entry = findMCEntry(MCOffset); if (entry == -1) return OptGCMap.ERROR; @@ -183,7 +193,6 @@ * @return an arraylist of CallSite objects representing all non-inlined * callsites in the method. Returns null if there are no such callsites. */ - @Interruptible public ArrayList<CallSite> getNonInlinedCallSites() { ArrayList<CallSite> ans = null; if (MCInformation == null) return ans; @@ -229,6 +238,7 @@ * Returns the GC map information for the GC map information entry passed * @param index GCmap entry */ + @Uninterruptible public int gcMapInformation(int index) { return OptGCMap.gcMapInformation(index, gcMaps); } @@ -238,6 +248,7 @@ * @param entry map entry * @param registerNumber the register number */ + @Uninterruptible public boolean registerIsSet(int entry, int registerNumber) { return OptGCMap.registerIsSet(entry, registerNumber, gcMaps); } @@ -245,6 +256,7 @@ /** * @return the next (relative) location or -1 for no more locations */ + @Uninterruptible public int nextLocation(int currentIndex) { return OptGCMap.nextLocation(currentIndex, gcMaps); } @@ -260,6 +272,7 @@ * * @param MCOffset the machine code offset of interest */ + @Uninterruptible private int findMCEntry(Offset MCOffset) { // Given a machine code instruction MCOffset, find the corresponding entry if (MCInformation == null) return -1; @@ -312,9 +325,9 @@ * the machine code mapping information for the entry. * It is called during the compilation of the method, not at GC time. * @param irMap the irmap to translate from + * @param DUMP_MAPS dump while we work */ - @Interruptible - private static OptMachineCodeMap generateMCInformation(GCIRMap irMap) { + private static OptMachineCodeMap generateMCInformation(GCIRMap irMap, boolean DUMP_MAPS) { CallSiteTree inliningMap = new CallSiteTree(); int numEntries = 0; @@ -460,6 +473,7 @@ * @param entry the index of the start of the entry * @return the MCOffset for this entry */ + @Uninterruptible private int getMCOffset(int entry) { if (isBigEntry(entry)) { int t = MCInformation[entry + BIG_OFFSET_IDX_ADJ]; @@ -478,6 +492,7 @@ * @param entry the index of the start of the entry * @return the GC map entry index for this entry (or -1 if none) */ + @Uninterruptible private int getGCMapIndex(int entry) { if (isBigEntry(entry)) { int t = MCInformation[entry + BIG_GCI_IDX_ADJ]; @@ -502,6 +517,7 @@ * @param entry the index of the start of the entry * @return the bytecode index for this entry (-1 if unknown) */ + @Uninterruptible private int getBytecodeIndex(int entry) { if (isBigEntry(entry)) { int t = MCInformation[entry + BIG_BCI_IDX_ADJ]; @@ -526,6 +542,7 @@ * @param entry the index of the start of the entry * @return the inline encoding index for this entry (-1 if unknown) */ + @Uninterruptible private int getInlineEncodingIndex(int entry) { if (isBigEntry(entry)) { int t = MCInformation[entry + BIG_IEI_IDX_ADJ]; @@ -550,6 +567,7 @@ * @param entry the index of the start of the entry * @return the call info for this entry */ + @Uninterruptible private int getCallInfo(int entry) { if (isBigEntry(entry)) { int t = MCInformation[entry + BIG_CALL_IDX_ADJ]; @@ -566,6 +584,8 @@ /** * Is the entry a big entry? */ + @Uninterruptible + @Inline private boolean isBigEntry(int entry) { if (VM.VerifyAssertions) { VM._assert((MCInformation[entry] & START_OF_ENTRY) == START_OF_ENTRY); @@ -576,6 +596,8 @@ /** * Is the entry a big entry? */ + @Uninterruptible + @Inline private boolean isHugeEntry(int entry) { if (VM.VerifyAssertions) { VM._assert((MCInformation[entry] & START_OF_ENTRY) == START_OF_ENTRY); @@ -587,13 +609,12 @@ // Debugging //////////////////////////////////////////// - @Interruptible - public void dumpMCInformation() { + public void dumpMCInformation(boolean DUMP_MAPS) { if (DUMP_MAPS) { VM.sysWrite(" Dumping the MCInformation\n"); if (MCInformation == null) return; for (int idx = 0; idx < MCInformation.length;) { - printMCInformationEntry(idx); + printMCInformationEntry(idx, DUMP_MAPS); idx = nextEntry(idx); } } @@ -603,8 +624,7 @@ * Prints the MCInformation for this entry * @param entry the entry to print */ - @Interruptible - private void printMCInformationEntry(int entry) { + private void printMCInformationEntry(int entry, boolean DUMP_MAPS) { if (DUMP_MAPS) { String sep = "\tMC: "; if (isBigEntry(entry)) sep = "B\tMC: "; @@ -648,9 +668,9 @@ * @param method * @param mapSize * @param machineCodeSize + * @param DUMP_MAP_SIZES */ - @Interruptible - private void recordStats(RVMMethod method, int mapSize, int machineCodeSize) { + private void recordStats(RVMMethod method, int mapSize, int machineCodeSize, boolean DUMP_MAP_SIZES) { if (DUMP_MAP_SIZES) { double mapMCPercent = (double) mapSize / machineCodeSize; VM.sysWrite(method); @@ -785,14 +805,6 @@ */ public final int[] inlineEncoding; /** - * Dump maps as methods are compiled. - */ - private static final boolean DUMP_MAPS = false; - /** - * Dump stats on map size as maps are compiled. - */ - private static final boolean DUMP_MAP_SIZES = false; - /** * Running totals for the size of machine code and maps */ private static int totalMCSize = 0; Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-09-03 20:38:15 UTC (rev 14950) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-09-03 20:40:52 UTC (rev 14951) @@ -240,6 +240,9 @@ PRINT_CALLING_CONVENTIONS -1 false Print IR after expanding calling conventions +PRINT_GC_MAPS -1 false +Print the garbage collection maps + ########## # Finally, the debugging flags # MUST start with DEBUG_ prefix This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-09-13 21:46:56
|
Revision: 14975 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14975&view=rev Author: captain5050 Date: 2008-09-13 21:46:51 +0000 (Sat, 13 Sep 2008) Log Message: ----------- RVM-651 WIP: add hook to allow IA32 assembler know whether a build is for 32 or 64bit addressing. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/VM.java rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/VM.fake Modified: rvmroot/trunk/rvm/src/org/jikesrvm/VM.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/VM.java 2008-09-13 21:39:49 UTC (rev 14974) +++ rvmroot/trunk/rvm/src/org/jikesrvm/VM.java 2008-09-13 21:46:51 UTC (rev 14975) @@ -2487,4 +2487,12 @@ Processor.getCurrentProcessor().enableThreadSwitching(); } + /** + * Is this a build for 32bit addressing? NB. this method is provided + * to give a hook to the IA32 assembler that won't be compiled away + * by javac + */ + public static boolean buildFor32Addr() { + return BuildFor32Addr; + } } Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/VM.fake =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/VM.fake 2008-09-13 21:39:49 UTC (rev 14974) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/VM.fake 2008-09-13 21:46:51 UTC (rev 14975) @@ -27,4 +27,6 @@ public static void _assert(boolean c, String s) { } public static void sysWrite(String s) { } + + public static boolean buildFor32Addr() { return true; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-09-13 21:59:20
|
Revision: 14978 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14978&view=rev Author: captain5050 Date: 2008-09-13 21:59:16 +0000 (Sat, 13 Sep 2008) Log Message: ----------- RVM-651: support for REX prefix (64bit Intel). Add javadoc to Intel assembler. Make nop parameterizable by size. Align branch targets to 4bytes for hot code. Switch get/put field to using pushs and pops. Fix test instruction size estimation. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java rvmroot/trunk/rvm/src/org/jikesrvm/jni/ia32/JNICompiler.java rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-09-13 21:50:20 UTC (rev 14977) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-09-13 21:59:16 UTC (rev 14978) @@ -2228,10 +2228,10 @@ protected final void emit_tableswitch(int defaultval, int low, int high) { int bTarget = biStart + defaultval; int mTarget = bytecodeMap[bTarget]; - int n = high - low + 1; // n = number of normal cases (0..n-1) + int n = high - low + 1; // n = number of normal cases (0..n-1) asm.emitPOP_Reg(T0); // T0 is index of desired case - asm.emitSUB_Reg_Imm(T0, low); // relativize T0 - asm.emitCMP_Reg_Imm(T0, n); // 0 <= relative index < n + asm.emitSUB_Reg_Imm(T0, low); // relativize T0 + asm.emitCMP_Reg_Imm(T0, n); // 0 <= relative index < n if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) { int firstCounter = edgeCounterIdx; @@ -2251,9 +2251,7 @@ // make table aligned if doing alignment checking if (VM.AlignmentChecking) { - while (((asm.getMachineCodeIndex() + 5) % WORDSIZE) != 0) { - asm.emitNOP(); - } + asm.emitNOP((asm.getMachineCodeIndex() + 1) & 3); } asm.emitCALL_Imm(asm.getMachineCodeIndex() + 5 + (n << LG_WORDSIZE)); @@ -2383,8 +2381,8 @@ } /* - * field access - */ + * field access + */ /** * Emit code to implement a dynamically linked getstatic @@ -2485,42 +2483,42 @@ if (MemoryManagerConstants.NEEDS_READ_BARRIER) { Barriers.compileGetfieldBarrier(asm, T0, fieldRef.getId()); } else { - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOV_Reg_RegIdx(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } } else if (fieldType.isBooleanType()) { // 8bit unsigned load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVZX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } else if (fieldType.isByteType()) { // 8bit signed load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVSX_Reg_RegIdx_Byte(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } else if (fieldType.isShortType()) { // 16bit signed load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVSX_Reg_RegIdx_Word(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } else if (fieldType.isCharType()) { // 16bit unsigned load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVZX_Reg_RegIdx_Word(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } else if (fieldType.isIntType() || fieldType.isFloatType() || fieldType.isWordType()) { // 32bit load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOV_Reg_RegIdx(T1, S0, T0, Assembler.BYTE, NO_SLOT); // T1 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T1); // replace reference with value on stack + asm.emitPUSH_Reg(T1); // place value on stack } else { // 64bit load if (VM.VerifyAssertions) VM._assert(fieldType.isLongType() || fieldType.isDoubleType()); // NB this is a 64bit copy from memory to the stack so implement // as a slightly optimized Intel memory copy using the FPU - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference - asm.emitSUB_Reg_Imm(SP, WORDSIZE); // adjust stack down one word to hold 64bit value + asm.emitPOP_Reg(S0); // S0 is object reference + asm.emitSUB_Reg_Imm(SP, 2*WORDSIZE); // adjust stack down to hold 64bit value if (SSE2_BASE) { asm.emitMOVQ_Reg_RegIdx(XMM0, S0, T0, Assembler.BYTE, NO_SLOT); // XMM0 is field value asm.emitMOVQ_RegInd_Reg(SP, XMM0); // replace reference with value on stack @@ -2545,42 +2543,42 @@ if (MemoryManagerConstants.NEEDS_READ_BARRIER && !field.isUntraced()) { Barriers.compileGetfieldBarrierImm(asm, fieldOffset, fieldRef.getId()); } else { - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOV_Reg_RegDisp(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } } else if (fieldType.isBooleanType()) { // 8bit unsigned load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVZX_Reg_RegDisp_Byte(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } else if (fieldType.isByteType()) { // 8bit signed load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVSX_Reg_RegDisp_Byte(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } else if (fieldType.isShortType()) { // 16bit signed load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVSX_Reg_RegDisp_Word(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } else if (fieldType.isCharType()) { // 16bit unsigned load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOVZX_Reg_RegDisp_Word(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } else if (fieldType.isIntType() || fieldType.isFloatType() || fieldType.isWordType()) { // 32bit load - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference + asm.emitPOP_Reg(S0); // S0 is object reference asm.emitMOV_Reg_RegDisp(T0, S0, fieldOffset); // T0 is field value - asm.emitMOV_RegDisp_Reg(SP, NO_SLOT, T0); // replace reference with value on stack + asm.emitPUSH_Reg(T0); // place value on stack } else { // 64bit load if (VM.VerifyAssertions) VM._assert(fieldType.isLongType() || fieldType.isDoubleType()); // NB this is a 64bit copy from memory to the stack so implement // as a slightly optimized Intel memory copy using the FPU - asm.emitMOV_Reg_RegDisp(S0, SP, NO_SLOT); // S0 is object reference - asm.emitSUB_Reg_Imm(SP, WORDSIZE); // adjust stack down one word to hold 64bit value + asm.emitPOP_Reg(S0); // S0 is object reference + asm.emitSUB_Reg_Imm(SP, 2*WORDSIZE); // adjust stack down to hold 64bit value if (SSE2_BASE) { asm.emitMOVQ_Reg_RegDisp(XMM0, S0, fieldOffset); // XMM0 is field value asm.emitMOVQ_RegInd_Reg(SP, XMM0); // replace reference with value on stack @@ -2605,28 +2603,24 @@ Barriers.compilePutfieldBarrier(asm, T0, fieldRef.getId()); asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference } else { - asm.emitMOV_Reg_RegDisp(T1, SP, NO_SLOT); // T1 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T1); // T1 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0+T0] <- T1 } } else if (fieldType.isBooleanType() || fieldType.isByteType()) { // 8bit store - asm.emitMOV_Reg_RegDisp(T1, SP, NO_SLOT); // T1 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T1); // T1 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference asm.emitMOV_RegIdx_Reg_Byte(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0+T0] <- T1 } else if (fieldType.isShortType() || fieldType.isCharType()) { // 16bit store - asm.emitMOV_Reg_RegDisp(T1, SP, NO_SLOT); // T1 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T1); // T1 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0+T0] <- T1 } else if (fieldType.isIntType() || fieldType.isFloatType() || fieldType.isWordType()) { // 32bit store - asm.emitMOV_Reg_RegDisp(T1, SP, NO_SLOT); // T1 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T1); // T1 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0+T0] <- T1 } else { // 64bit store @@ -2660,31 +2654,27 @@ Barriers.compilePutfieldBarrierImm(asm, fieldOffset, fieldRef.getId()); asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference } else { - asm.emitMOV_Reg_RegDisp(T0, SP, NO_SLOT); // T0 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T0); // T0 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference // [S0+fieldOffset] <- T0 asm.emitMOV_RegDisp_Reg(S0, fieldOffset, T0); } } else if (field.getSize() == BYTES_IN_BYTE) { // 8bit store - asm.emitMOV_Reg_RegDisp(T0, SP, NO_SLOT); // T0 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T0); // T0 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference // [S0+fieldOffset] <- T0 asm.emitMOV_RegDisp_Reg_Byte(S0, fieldOffset, T0); } else if (field.getSize() == BYTES_IN_SHORT) { // 16bit store - asm.emitMOV_Reg_RegDisp(T0, SP, NO_SLOT); // T0 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T0); // T0 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference // [S0+fieldOffset] <- T0 asm.emitMOV_RegDisp_Reg_Word(S0, fieldOffset, T0); } else if (field.getSize() == BYTES_IN_INT) { // 32bit store - asm.emitMOV_Reg_RegDisp(T0, SP, NO_SLOT); // T0 is the value to be stored - asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT); // S0 is the object reference - asm.emitADD_Reg_Imm(SP, WORDSIZE * 2); // complete popping the value and reference + asm.emitPOP_Reg(T0); // T0 is the value to be stored + asm.emitPOP_Reg(S0); // S0 is the object reference // [S0+fieldOffset] <- T0 asm.emitMOV_RegDisp_Reg(S0, fieldOffset, T0); } else { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-09-13 21:50:20 UTC (rev 14977) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-09-13 21:59:16 UTC (rev 14978) @@ -653,20 +653,22 @@ */ protected boolean targetIsClose(Instruction start, int target) { Instruction inst = start.nextInstructionInCodeOrder(); - int budget = 120; // slight fudge factor could be 127 + final int budget = 120; // slight fudge factor could be 127 + int offset = 0; while (true) { - if (budget <= 0) return false; + if (offset <= budget) return false; if (inst.getmcOffset() == target) { return true; } - budget -= estimateSize(inst); + offset += estimateSize(inst, offset); inst = inst.nextInstructionInCodeOrder(); } } - protected int estimateSize(Instruction inst) { + protected int estimateSize(Instruction inst, int offset) { switch (inst.getOpcode()) { case LABEL_opcode: + return (4 - offset) & 3; // return size of nop required for alignment case BBEND_opcode: case UNINT_BEGIN_opcode: case UNINT_END_opcode: { @@ -693,8 +695,8 @@ } case IA32_TEST_opcode: { int size = 2; // opcode + modr/m - size += operandCost(MIR_Test.getVal1(inst), true); - size += operandCost(MIR_Test.getVal2(inst), true); + size += operandCost(MIR_Test.getVal1(inst), false); + size += operandCost(MIR_Test.getVal2(inst), false); return size; } case IA32_ADDSD_opcode: @@ -1004,7 +1006,7 @@ for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) { if (DEBUG_ESTIMATE) { int start = asm.getMachineCodeIndex(); - int estimate = asm.estimateSize(p); + int estimate = asm.estimateSize(p, start); asm.doInst(p); int end = asm.getMachineCodeIndex(); if (end - start > estimate) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/jni/ia32/JNICompiler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/jni/ia32/JNICompiler.java 2008-09-13 21:50:20 UTC (rev 14977) +++ rvmroot/trunk/rvm/src/org/jikesrvm/jni/ia32/JNICompiler.java 2008-09-13 21:59:16 UTC (rev 14978) @@ -831,7 +831,7 @@ // finally proceed with the normal Java compiled code // skip the thread switch test for now, see BaselineCompilerImpl.genThreadSwitchTest(true) - asm.emitNOP(); // end of prologue marker + asm.emitNOP(1); // end of prologue marker } public static void generateEpilogForJNIMethod(Assembler asm, RVMMethod method) { Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-09-13 21:50:20 UTC (rev 14977) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-09-13 21:59:16 UTC (rev 14978) @@ -461,6 +461,26 @@ private static final byte SIBforESP = (byte) ((0<<6) + (4<<3) + ESP.value()); // (scale factor 1) no index, ESP is base /** + * Generate a REX prefix if necessary + * + * @param W is a quad word override needed + * @param R_reg extension of the modrm field + * @param X_reg extension of the SIB index field + * @param B_reg extension of the modrm field, SIB base or opcode reg field + */ + @Inline + private void generateREXprefix(boolean W, MachineRegister R_reg, MachineRegister X_reg, MachineRegister B_reg) { + boolean R = R_reg != null && R_reg.needsREXprefix(); + boolean X = X_reg != null && X_reg.needsREXprefix(); + boolean B = B_reg != null && B_reg.needsREXprefix(); + if (W || R || X || B) { + if (VM.VerifyAssertions) VM._assert(!VM.buildFor32Addr()); + byte prefixByte = (byte)(0x40 | (W ? 8 : 0) | (R ? 4 : 0) | (X ? 2 : 0) | (B ? 1 : 0)); + setMachineCodes(mi++, prefixByte); + } + } + + /** * Return a ModRM byte encoding a source and destination register * (i.e. for a register-register instruction). * @@ -470,7 +490,7 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) private byte regRegModRM(MachineRegister reg1, MachineRegister reg2) { - return (byte) ((3 << 6) | (reg2.value() << 3) | reg1.value()); + return (byte) ((3 << 6) | ((reg2.value() & 7) << 3) | (reg1.value() & 0x7)); } /** @@ -484,7 +504,7 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) private byte regDisp32RegModRM(MachineRegister reg1, MachineRegister reg2) { - return (byte) ((2 << 6) | (reg2.value() << 3) | reg1.value()); + return (byte) ((2 << 6) | ((reg2.value() & 7)<< 3) | (reg1.value() & 7)); } /** @@ -498,7 +518,7 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) private byte regDisp8RegModRM(MachineRegister reg1, MachineRegister reg2) { - return (byte) ((1 << 6) | (reg2.value() << 3) | reg1.value()); + return (byte) ((1 << 6) | ((reg2.value() & 7) << 3) | (reg1.value() & 7)); } /** @@ -511,7 +531,7 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) private byte regIndirectRegModRM(MachineRegister reg1, MachineRegister reg2) { - return (byte) ((reg2.value() << 3) | reg1.value()); + return (byte) (((reg2.value() & 7) << 3) | (reg1.value() & 7)); } /** @@ -527,7 +547,7 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) private byte sib(short scale, MachineRegister baseReg, MachineRegister indexReg) { - return (byte) ((scale << 6) | (indexReg.value() << 3) | baseReg.value()); + return (byte) ((scale << 6) | ((indexReg.value() & 7) << 3) | (baseReg.value() & 7)); } /** @@ -859,12 +879,12 @@ @Inline public final void emitPatchPoint() { if ((mi & 0x1) == 1) { - emitNOP(); + emitNOP(1); } ForwardReference r = forwardJMP(); - emitNOP(); - emitNOP(); - emitNOP(); + emitNOP(1); + emitNOP(1); + emitNOP(1); r.resolve(this); } @@ -1063,6 +1083,10 @@ * branch to patch. */ public final void patchUnconditionalBranch (int sourceIndex) { + if (VM.AlignmentChecking || isHotCode()) { + // force 4byte alignment here + emitNOP((4 - mi) & 3); + } if (lister != null) lister.comefrom(mi, sourceIndex); int relOffset = mi - (sourceIndex+5); sourceIndex++; // skip the op code @@ -1079,6 +1103,10 @@ * branch to patch. */ public final void patchConditionalBranch (int sourceIndex) { + if (VM.AlignmentChecking || isHotCode()) { + // force 4byte alignment here + emitNOP((4 - mi) & 3); + } if (lister != null) lister.comefrom(mi, sourceIndex); int relOffset = mi - (sourceIndex+6); sourceIndex += 2; // skip the (two byte) op code @@ -1096,9 +1124,13 @@ * branch to patch. */ public final void patchShortBranch (int sourceIndex) { + if (VM.AlignmentChecking || isHotCode()) { + // force 4byte alignment here + emitNOP((4 - mi) & 3); + } if (lister != null) lister.comefrom(mi, sourceIndex); int relOffset = mi - (sourceIndex+2); - if (VM.VerifyAssertions) VM._assert(fits(relOffset, 8)); + if (VM.VerifyAssertions) VM._assert(fits(relOffset, 8), "offset too large: "+relOffset); sourceIndex++; // skip the op code emitImm8((byte)relOffset, sourceIndex); } @@ -1181,6 +1213,10 @@ * @param sourceIndex the location of the offset to patch */ public final void patchSwitchCase (int sourceIndex) { + if (VM.AlignmentChecking || isHotCode()) { + // force 4byte alignment here + emitNOP((4 - mi) & 3); + } if (lister != null) lister.comefrom(mi, sourceIndex); int c = 0; c |= (machineCodes[sourceIndex+0] & 0xFF) << 0; @@ -1199,6 +1235,40 @@ ///////////////////////////////////// /** + * Generate a bswap on a register. That is, + * <PRE> + * bswap reg + * </PRE> + * + * @param reg register to operate upon + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + public final void emitBSWAP_Reg(GPR reg) { + int miStart = mi; + generateREXprefix(false, null, null, reg); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) (0xC8 | (reg.value() & 7))); + if (lister != null) lister.R(miStart, "bswap", reg); + } + + /** + * Generate a bswap on a quad register. That is, + * <PRE> + * bswap reg + * </PRE> + * + * @param reg register to operate upon + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + public final void emitBSWAP_Reg_Quad(GPR reg) { + int miStart = mi; + generateREXprefix(true, null, null, reg); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) (0xC8 | (reg.value() & 7))); + if (lister != null) lister.R(miStart, "bswap", reg); + } + + /** * Conditionally move the source to the destination, i.e. * <PRE> * if (cond) dst = src @@ -1635,10 +1705,82 @@ if (lister != null) lister.OP(miStart, "PAUSE"); } - // nop - public final void emitNOP () { + /** + * Emit NOP instruction + * + * @param length size of NOP instruction required + */ + public final void emitNOP (int length) { int miStart = mi; - setMachineCodes(mi++, (byte) 0x90); + switch (length) { + case 0: + break; + case 1: + setMachineCodes(mi++, (byte) 0x90); + break; + case 2: + setMachineCodes(mi++, (byte) 0x66); + setMachineCodes(mi++, (byte) 0x90); + break; + case 3: + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x00); + break; + case 4: + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x40); + setMachineCodes(mi++, (byte) 0x00); + break; + case 5: + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x44); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + break; + case 6: + setMachineCodes(mi++, (byte) 0x66); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x44); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + break; + case 7: + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x80); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + break; + case 8: + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x84); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + break; + case 9: + setMachineCodes(mi++, (byte) 0x66); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0x1F); + setMachineCodes(mi++, (byte) 0x84); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + setMachineCodes(mi++, (byte) 0x00); + break; + default: + throw new Error("Unexpected NOP length "+length); + } if (lister != null) lister.OP(miStart, "NOP"); } Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-09-13 21:50:20 UTC (rev 14977) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-09-13 21:59:16 UTC (rev 14978) @@ -25,35 +25,44 @@ sizeOrPrefix=$5 ext= code= - prefix= + prefix="// no group 1 to 4 prefix byte" + twobyteop="// single byte opcode" + rex_w=false if [ x$sizeOrPrefix = xbyte ]; then ext=_Byte code=" (byte) " elif [ x$sizeOrPrefix = xword ]; then ext=_Word code=" (word) " - prefix=" - setMachineCodes(mi++, (byte) 0x66);" + prefix="setMachineCodes(mi++, (byte) 0x66);" + elif [ x$sizeOrPrefix = xquad ]; then + ext=_Quad + code=" (quad) " + rex_w=true + elif [ x$sizeOrPrefix = x0x0F ]; then + twobyteop="setMachineCodes(mi++, (byte) 0x0F);" elif [ x$sizeOrPrefix != x ]; then - prefix=" - setMachineCodes(mi++, (byte) $sizeOrPrefix);" + prefix="setMachineCodes(mi++, (byte) $sizeOrPrefix);" fi cat >> $FILENAME <<EOF /** - * Generate a register--register ${acronym}. That is, + * Generate a register(indirect)--register ${acronym}. That is, * <PRE> - * [dstReg] ${opStr}= ${code} srcReg + * [dstBase] ${opStr}= ${code} srcReg * </PRE> * - * @param dstReg the destination register + * @param dstBase the destination base * @param srcReg the source register */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emit${acronym}_RegInd_Reg${ext}(GPR dstReg, GPR srcReg) { - int miStart = mi; ${prefix} + public final void emit${acronym}_RegInd_Reg${ext}(GPR dstBase, GPR srcReg) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, null, dstBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); - emitRegIndirectRegOperands(dstReg, srcReg); - if (lister != null) lister.RNR(miStart, "${acronym}", dstReg, srcReg); + emitRegIndirectRegOperands(dstBase, srcReg); + if (lister != null) lister.RNR(miStart, "${acronym}", dstBase, srcReg); } /** @@ -69,43 +78,94 @@ */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,4}) public final void emit${acronym}_RegOff_Reg${ext}(GPR dstIndex, short dstScale, Offset dstDisp, GPR srcReg) { - int miStart = mi; ${prefix} + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, dstIndex, null); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); emitRegOffRegOperands(dstIndex, dstScale, dstDisp, srcReg); if (lister != null) lister.RFDR(miStart, "${acronym}", dstIndex, dstScale, dstDisp, srcReg); } - // [dstDisp] ${opStr}= $code srcReg + /** + * Generate a absolute--register ${acronym}. That is, + * <PRE> + * [dstDisp] ${opStr}= ${code} srcReg + * </PRE> + * + * @param dstDisp the destination address + * @param srcReg the source register + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emit${acronym}_Abs_Reg${ext}(Address dstDisp, GPR srcReg) { - int miStart = mi; ${prefix} + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, null, null); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); emitAbsRegOperands(dstDisp, srcReg); if (lister != null) lister.RAR(miStart, "${acronym}", dstDisp, srcReg); } - // [dstBase + dstIndex<<scale + dstDisp] ${opStr}= $code srcReg + /** + * Generate a register-index--register ${acronym}. That is, + * <PRE> + * [dstBase + dstIndex<<dstScale + dstDisp] ${opStr}= $code srcReg + * </PRE> + * + * @param dstBase the base register + * @param dstIndex the destination index register + * @param dstScale the destination shift amount + * @param dstDisp the destination displacement + * @param srcReg the source register + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2,5}) - public final void emit${acronym}_RegIdx_Reg${ext}(GPR dstBase, GPR dstIndex, short scale, Offset dstDisp, GPR srcReg) { - int miStart = mi; ${prefix} + public final void emit${acronym}_RegIdx_Reg${ext}(GPR dstBase, GPR dstIndex, short dstScale, Offset dstDisp, GPR srcReg) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, dstIndex, dstBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); - emitSIBRegOperands(dstBase, dstIndex, scale, dstDisp, srcReg); - if (lister != null) lister.RXDR(miStart, "${acronym}", dstBase, dstIndex, scale, dstDisp, srcReg); + emitSIBRegOperands(dstBase, dstIndex, dstScale, dstDisp, srcReg); + if (lister != null) lister.RXDR(miStart, "${acronym}", dstBase, dstIndex, dstScale, dstDisp, srcReg); } - // [dstReg + dstDisp] ${opStr}= $code srcReg + /** + * Generate a register-displacement--register ${acronym}. That is, + * <PRE> + * [dstBase + dstDisp] ${opStr}= $code srcReg + * </PRE> + * + * @param dstBase the base register + * @param dstDisp the destination displacement + * @param srcReg the source register + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,3}) - public final void emit${acronym}_RegDisp_Reg${ext}(GPR dstReg, Offset disp, GPR srcReg) { - int miStart = mi; ${prefix} + public final void emit${acronym}_RegDisp_Reg${ext}(GPR dstBase, Offset dstDisp, GPR srcReg) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, null, dstBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); - emitRegDispRegOperands(dstReg, disp, srcReg); - if (lister != null) lister.RDR(miStart, "${acronym}", dstReg, disp, srcReg); + emitRegDispRegOperands(dstBase, dstDisp, srcReg); + if (lister != null) lister.RDR(miStart, "${acronym}", dstBase, dstDisp, srcReg); } - // dstReg ${opStr}= $code srcReg + /** + * Generate a register--register ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code srcReg + * </PRE> + * + * @param dstReg the destination register + * @param srcReg the source register + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) public final void emit${acronym}_Reg_Reg${ext}(GPR dstReg, GPR srcReg) { - int miStart = mi; ${prefix} + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, srcReg, null, dstReg); + ${twobyteop} setMachineCodes(mi++, (byte) ${rmrCode}); emitRegRegOperands(dstReg, srcReg); if (lister != null) lister.RR(miStart, "${acronym}", dstReg, srcReg); @@ -114,49 +174,110 @@ EOF if [ x$rrmCode != xnone ]; then cat >> $FILENAME <<EOF - // dstReg ${opStr}= $code [srcReg + srcDisp] - @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2,3}) - public final void emit${acronym}_Reg_RegDisp${ext}(GPR dstReg, GPR srcReg, Offset disp) { - int miStart = mi; ${prefix} + /** + * Generate a register--register-displacement ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code [srcReg + srcDisp] + * </PRE> + * + * @param dstReg the destination register + * @param srcBase the source register + * @param srcDisp the source displacement + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emit${acronym}_Reg_RegDisp${ext}(GPR dstReg, GPR srcBase, Offset srcDisp) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, dstReg, null, srcBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rrmCode}); - emitRegDispRegOperands(srcReg, disp, dstReg); - if (lister != null) lister.RRD(miStart, "${acronym}", dstReg, srcReg, disp); + emitRegDispRegOperands(srcBase, srcDisp, dstReg); + if (lister != null) lister.RRD(miStart, "${acronym}", dstReg, srcBase, srcDisp); } - // dstReg ${opStr}= $code [srcIndex<<scale + srcDisp] + /** + * Generate a register--register-offset ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code [srcIndex<<srcScale + srcDisp] + * </PRE> + * + * @param dstReg the destination register + * @param srcIndex the source index register + * @param srcScale the source shift amount + * @param srcDisp the source displacement + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emit${acronym}_Reg_RegOff${ext}(GPR dstReg, GPR srcIndex, short scale, Offset srcDisp) { - int miStart = mi; ${prefix} + public final void emit${acronym}_Reg_RegOff${ext}(GPR dstReg, GPR srcIndex, short srcScale, Offset srcDisp) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, dstReg, srcIndex, null); + ${twobyteop} setMachineCodes(mi++, (byte) ${rrmCode}); - emitRegOffRegOperands(srcIndex, scale, srcDisp, dstReg); - if (lister != null) lister.RRFD(miStart, "${acronym}", dstReg, srcIndex, scale, srcDisp); + emitRegOffRegOperands(srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRFD(miStart, "${acronym}", dstReg, srcIndex, srcScale, srcDisp); } - // dstReg ${opStr}= $code [srcDisp] + /** + * Generate a register--register-offset ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code [srcDisp] + * </PRE> + * + * @param dstReg the destination register + * @param srcDisp the source displacement + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) public final void emit${acronym}_Reg_Abs${ext}(GPR dstReg, Address srcDisp) { - int miStart = mi; ${prefix} + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, dstReg, null, null); + ${twobyteop} setMachineCodes(mi++, (byte) ${rrmCode}); emitAbsRegOperands(srcDisp, dstReg); if (lister != null) lister.RRA(miStart, "${acronym}", dstReg, srcDisp); } - // dstReg ${opStr}= $code [srcBase + srcIndex<<scale + srcDisp] + /** + * Generate a register--register-offset ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code [srcBase + srcIndex<<srcScale + srcDisp] + * </PRE> + * + * @param dstReg the destination register + * @param srcBase the source base register + * @param srcIndex the source index register + * @param srcScale the source shift amount + * @param srcDisp the source displacement + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2,3}) - public final void emit${acronym}_Reg_RegIdx${ext}(GPR dstReg, GPR srcBase, GPR srcIndex, short scale, Offset srcDisp) { - int miStart = mi; ${prefix} + public final void emit${acronym}_Reg_RegIdx${ext}(GPR dstReg, GPR srcBase, GPR srcIndex, short srcScale, Offset srcDisp) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, dstReg, srcIndex, srcBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rrmCode}); - emitSIBRegOperands(srcBase, srcIndex, scale, srcDisp, dstReg); - if (lister != null) lister.RRXD(miStart, "${acronym}", dstReg, srcBase, srcIndex, scale, srcDisp); + emitSIBRegOperands(srcBase, srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRXD(miStart, "${acronym}", dstReg, srcBase, srcIndex, srcScale, srcDisp); } - // dstReg ${opStr}= $code [srcReg] + /** + * Generate a register--register(indirect) ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= $code [srcBase] + * </PRE> + * + * @param dstReg the destination register + * @param srcBase the source base register + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emit${acronym}_Reg_RegInd${ext}(GPR dstReg, GPR srcReg) { - int miStart = mi; ${prefix} + public final void emit${acronym}_Reg_RegInd${ext}(GPR dstReg, GPR srcBase) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, dstReg, null, srcBase); + ${twobyteop} setMachineCodes(mi++, (byte) ${rrmCode}); - emitRegIndirectRegOperands(srcReg, dstReg); - if (lister != null) lister.RRN(miStart, "${acronym}", dstReg, srcReg); + emitRegIndirectRegOperands(srcBase, dstReg); + if (lister != null) lister.RRN(miStart, "${acronym}", dstReg, srcBase); } EOF @@ -174,24 +295,40 @@ sizeOrPrefix=$7 local ext= local code= - local prefix= + local prefix="// no group 1 to 4 prefix byte" + local twobyteop="// single byte opcode" + local emitImm=emitImm32 + local rex_w=false if [ x$sizeOrPrefix = xword ]; then ext=_Word code=" (word) " emitImm=emitImm16 - prefix=" - setMachineCodes(mi++, (byte) 0x66);" + prefix="setMachineCodes(mi++, (byte) 0x66);" + elif [ x$sizeOrPrefix = xquad ]; then + ext=_Quad + code=" (quad) " + rex_w=true + elif [ x$sizeOrPrefix = x0x0F ]; then + twobyteop="setMachineCodes(mi++, (byte) 0x0F);" elif [ x$sizeOrPrefix != x ]; then - prefix=" - setMachineCodes(mi++, (byte) $sizeOrPrefix);" - else - emitImm=emitImm32 + prefix="setMachineCodes(mi++, (byte) $sizeOrPrefix);" fi cat >> $FILENAME <<EOF - // dstReg ${opStr}= ${code} imm + /** + * Generate a register--immediate ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= ${code} imm + * </PRE> + * + * @param dstReg the destination register + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) public final void emit${acronym}_Reg_Imm${ext}(GPR dstReg, int imm) { - int miStart = mi;$prefix + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, null, dstReg); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -200,43 +337,55 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$eaxOpcode != xnone ]; then cat >> $FILENAME <<EOF } else if (dstReg == EAX) { - setMachineCodes(mi++, (byte) $eaxOpcode); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) $eaxOpcode); + ${emitImm}(imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi cat >> $FILENAME <<EOF - if (lister != null) lister.RI(miStart, "${acronym}", dstReg, imm); - } + if (lister != null) lister.RI(miStart, "${acronym}", dstReg, imm); + } - // [dstReg + dstDisp] ${opStr}= ${code} imm + /** + * Generate a register-displacement--immediate ${acronym}. That is, + * <PRE> + * [dstBase + dstDisp] ${opStr}= ${code} imm + * </PRE> + * + * @param dstBase the destination register + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegDisp_Imm${ext}(GPR dstReg, Offset disp, int imm) { - int miStart = mi;$prefix + public final void emit${acronym}_RegDisp_Imm${ext}(GPR dstBase, Offset dstDisp, int imm) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, null, dstBase); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -245,36 +394,49 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegDispRegOperands(dstReg, disp, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegDispRegOperands(dstBase, dstDisp, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegDispRegOperands(dstReg, disp, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegDispRegOperands(dstBase, dstDisp, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi cat >> $FILENAME <<EOF - if (lister != null) lister.RDI(miStart, "${acronym}", dstReg, disp, imm); + if (lister != null) lister.RDI(miStart, "${acronym}", dstBase, dstDisp, imm); } - // [dstIndex<<scale + dstDisp] ${opStr}= ${code} imm + /** + * Generate a register-offset--immediate ${acronym}. That is, + * <PRE> + * [dstIndex<<dstScale + dstDisp] ${opStr}= ${code} imm + * </PRE> + * + * @param dstIndex the destination index register + * @param dstScale the destination shift amount + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegOff_Imm${ext}(GPR dstIndex, short scale, Offset dstDisp, int imm) { - int miStart = mi;$prefix + public final void emit${acronym}_RegOff_Imm${ext}(GPR dstIndex, short dstScale, Offset dstDisp, int imm) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, dstIndex, null); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -283,35 +445,46 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegOffRegOperands(dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegOffRegOperands(dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegOffRegOperands(dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegOffRegOperands(dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi cat >> $FILENAME <<EOF - if (lister != null) lister.RFDI(miStart, "${acronym}", dstIndex, scale, dstDisp, imm); + if (lister != null) lister.RFDI(miStart, "${acronym}", dstIndex, dstScale, dstDisp, imm); } - // [dstDisp] ${opStr}= ${code} imm + /** + * Generate a absolute--immediate ${acronym}. That is, + * <PRE> + * [dstDisp] ${opStr}= ${code} imm + * </PRE> + * + * @param dstDisp the destination displacement + * @param imm immediate + */ public final void emit${acronym}_Abs_Imm${ext}(Address dstDisp, int imm) { - int miStart = mi;$prefix + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, null, null); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -320,25 +493,25 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitAbsRegOperands(dstDisp, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitAbsRegOperands(dstDisp, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitAbsRegOperands(dstDisp, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitAbsRegOperands(dstDisp, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi @@ -346,10 +519,24 @@ if (lister != null) lister.RAI(miStart, "${acronym}", dstDisp, imm); } - // [dstBase + dstIndex<<scale + dstDisp] ${opStr}= ${code} imm + /** + * Generate a register-index--immediate ${acronym}. That is, + * <PRE> + * [dstBase + dstIndex<<dstScale + dstDisp] ${opStr}= ${code} imm + * </PRE> + * + * @param dstBase the destination base register + * @param dstIndex the destination index register + * @param dstScale the destination shift amount + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emit${acronym}_RegIdx_Imm${ext}(GPR dstBase, GPR dstIndex, short scale, Offset dstDisp, int imm) { - int miStart = mi;$prefix + public final void emit${acronym}_RegIdx_Imm${ext}(GPR dstBase, GPR dstIndex, short dstScale, Offset dstDisp, int imm) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, dstIndex, dstBase); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -358,36 +545,47 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitSIBRegOperands(dstBase, dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitSIBRegOperands(dstBase, dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitSIBRegOperands(dstBase, dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitSIBRegOperands(dstBase, dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi cat >> $FILENAME <<EOF - if (lister != null) lister.RXDI(miStart, "${acronym}", dstBase, dstIndex, scale, dstDisp, imm); + if (lister != null) lister.RXDI(miStart, "${acronym}", dstBase, dstIndex, dstScale, dstDisp, imm); } - // [dstReg] ${opStr}= ${code} imm + /** + * Generate a register(indirect)--immediate ${acronym}. That is, + * <PRE> + * [dstBase] ${opStr}= ${code} imm + * </PRE> + * + * @param dstBase the destination base register + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegInd_Imm${ext}(GPR dstReg, int imm) { - int miStart = mi;$prefix + public final void emit${acronym}_RegInd_Imm${ext}(GPR dstBase, int imm) { + int miStart = mi; + ${prefix} + generateREXprefix(${rex_w}, null, null, dstBase); + ${twobyteop} EOF if [ x$imm8Code = xnone ]; then cat >> $FILENAME <<EOF @@ -396,30 +594,30 @@ else cat >> $FILENAME <<EOF if (fits(imm,8)) { - setMachineCodes(mi++, (byte) ${imm8Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegIndirectRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); - emitImm8((byte)imm); + setMachineCodes(mi++, (byte) ${imm8Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegIndirectRegOperands(dstBase, GPR.getForOpcode(${immExtOp})); + emitImm8((byte)imm); EOF fi if [ x$imm32Code = xnone ]; then cat >> $FILENAME <<EOF } else { - throw new InternalError("Data too large for ${acronym} instruction"); + throw new InternalError("Data too large for ${acronym} instruction"); } EOF else cat >> $FILENAME <<EOF } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegIndirectRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); - ${emitImm}(imm); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegIndirectRegOperands(dstBase, GPR.getForOpcode(${immExtOp})); + ${emitImm}(imm); } EOF fi cat >> $FILENAME <<EOF - if (lister != null) lister.RNI(miStart, "${acronym}", dstReg, imm); + if (lister != null) lister.RNI(miStart, "${acronym}", dstBase, imm); } EOF @@ -436,60 +634,110 @@ size=$7 ext= code= - prefix= cat >> $FILENAME <<EOF - // dstReg ${opStr}= (byte) imm + /** + * Generate a register--immediate ${acronym}. That is, + * <PRE> + * dstReg ${opStr}= (byte) imm + * </PRE> + * + * @param dstReg the destination register + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) public final void emit${acronym}_Reg_Imm_Byte(GPR dstReg, int imm) { int miStart = mi; if (dstReg == EAX) { - setMachineCodes(mi++, (byte) $eaxOpcode); - emitImm8(imm); + setMachineCodes(mi++, (byte) $eaxOpcode); + emitImm8(imm); } else { - setMachineCodes(mi++, (byte) ${imm32Code}); - // "register ${immExtOp}" is really part of the opcode - emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); - emitImm8(imm); + generateREXprefix(false, null, null, dstReg); + setMachineCodes(mi++, (byte) ${imm32Code}); + // "register ${immExtOp}" is really part of the opcode + emitRegRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); + emitImm8(imm); } - if (lister != null) lister.RI(miStart, "${acronym}", dstReg, imm); - } + if (lister != null) lister.RI(miStart, "${acronym}", dstReg, imm); + } - // [dstReg + dstDisp] ${opStr}= (byte) imm + /** + * Generate a register-displacement--immediate ${acronym}. That is, + * <PRE> + * [dstBase + dstDisp] ${opStr}= (byte) imm + * </PRE> + * + * @param dstBase the destination register + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegDisp_Imm_Byte(GPR dstReg, Offset disp, int imm) { + public final void emit${acronym}_RegDisp_Imm_Byte(GPR dstBase, Offset dstDisp, int imm) { int miStart = mi; + generateREXprefix(false, null, null, dstBase); setMachineCodes(mi++, (byte) ${imm32Code}); // "register ${immExtOp}" is really part of the opcode - emitRegDispRegOperands(dstReg, disp, GPR.getForOpcode(${immExtOp})); + emitRegDispRegOperands(dstBase, dstDisp, GPR.getForOpcode(${immExtOp})); emitImm8(imm); - if (lister != null) lister.RDI(miStart, "${acronym}", dstReg, disp, imm); + if (lister != null) lister.RDI(miStart, "${acronym}", dstBase, dstDisp, imm); } - // [dstBase + dstIndex<<scale + dstDisp] ${opStr}= (byte) imm + /** + * Generate a register-index--immediate ${acronym}. That is, + * <PRE> + * [dstBase + dstIndex<<scale + dstDisp] ${opStr}= (byte) imm + * </PRE> + * + * @param dstBase the destination base register + * @param dstIndex the destination index register + * @param dstScale the destination shift amount + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emit${acronym}_RegIdx_Imm_Byte(GPR dstBase, GPR dstIndex, short scale, Offset dstDisp, int imm) { + public final void emit${acronym}_RegIdx_Imm_Byte(GPR dstBase, GPR dstIndex, short dstScale, Offset dstDisp, int imm) { int miStart = mi; + generateREXprefix(false, null, dstIndex, dstBase); setMachineCodes(mi++, (byte) ${imm32Code}); // "register ${immExtOp}" is really part of the opcode - emitSIBRegOperands(dstBase, dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); + emitSIBRegOperands(dstBase, dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); emitImm8(imm); - if (lister != null) lister.RXDI(miStart, "${acronym}", dstBase, dstIndex, scale, dstDisp, imm); + if (lister != null) lister.RXDI(miStart, "${acronym}", dstBase, dstIndex, dstScale, dstDisp, imm); } - // [dstIndex<<scale + dstDisp] ${opStr}= (byte) imm + /** + * Generate a register-offset--immediate ${acronym}. That is, + * <PRE> + * [dstIndex<<dstScale + dstDisp] ${opStr}= (byte) imm + * </PRE> + * + * @param dstIndex the destination index register + * @param dstScale the destination shift amount + * @param dstDisp the destination displacement + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegOff_Imm_Byte(GPR dstIndex, short scale, Offset dstDisp, int imm) { + public final void emit${acronym}_RegOff_Imm_Byte(GPR dstIndex, short dstScale, Offset dstDisp, int imm) { int miStart = mi; + generateREXprefix(false, null, dstIndex, null); setMachineCodes(mi++, (byte) ${imm32Code}); // "register ${immExtOp}" is really part of the opcode - emitRegOffRegOperands(dstIndex, scale, dstDisp, GPR.getForOpcode(${immExtOp})); + emitRegOffRegOperands(dstIndex, dstScale, dstDisp, GPR.getForOpcode(${immExtOp})); emitImm8(imm); - if (lister != null) lister.RFDI(miStart, "${acronym}", dstIndex, scale, dstDisp, imm); + if (lister != null) lister.RFDI(miStart, "${acronym}", dstIndex, dstScale, dstDisp, imm); } - // [dstDisp] ${opStr}= (byte) imm + /** + * Generate a absolute--immediate ${acronym}. That is, + * <PRE> + * [dstDisp] ${opStr}= (byte) imm + * </PRE> + * + * @param dstDisp the destination displacement + * @param imm immediate + */ public final void emit${acronym}_Abs_Imm_Byte(Address dstDisp, int imm) { int miStart = mi; + generateREXprefix(false, null, null, null); setMachineCodes(mi++, (byte) ${imm32Code}); // "register ${immExtOp}" is really part of the opcode emitAbsRegOperands(dstDisp, GPR.getForOpcode(${immExtOp})); @@ -497,15 +745,24 @@ if (lister != null) lister.RAI(miStart, "${acronym}", dstDisp, imm); } - // [dstReg] ${opStr}= (byte) imm + /** + * Generate a register(indirect)--immediate ${acronym}. That is, + * <PRE> + * [dstBase] ${opStr}= (byte) imm + * </PRE> + * + * @param dstBase the destination base register + * @param imm immediate + */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emit${acronym}_RegInd_Imm_Byte(GPR dstReg, int imm) { + public final void emit${acronym}_RegInd_Imm_Byte(GPR dstBase, int imm) { int miStart = mi; + generateREXprefix(false, null, null, dstBase); setMachineCodes(mi++, (byte) ${imm32Code}); // "register ${immExtOp}" is really part of the opcode - emitRegIndirectRegOperands(dstReg, GPR.getForOpcode(${immExtOp})); + emitRegIndirectRegOperands(dstBase, GPR.getForOpcode(${immExtOp})); emitImm8(imm); - if (lister != null) lister.RNI(miStart, "${acronym}", dstReg, imm); + if (lister != null) lister.RNI(miStart, "${acronym}", dstBase, imm); } ... [truncated message content] |
From: <cap...@us...> - 2008-09-30 23:01:29
|
Revision: 15029 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15029&view=rev Author: captain5050 Date: 2008-09-30 23:01:03 +0000 (Tue, 30 Sep 2008) Log Message: ----------- RVM-671: Compute size of stack location operand based on the type of the register rather than 4 for int/long/reference types and 8 for floating point. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ComplexLIR2MIRExpansion.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/CallingConvention.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/StackManager.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-09-30 22:47:54 UTC (rev 15028) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-09-30 23:01:03 UTC (rev 15029) @@ -3047,11 +3047,13 @@ for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams;) { Operand param = params[paramIdx++]; if (param instanceof RegisterOperand) { - MIR_Call.setParam(s, mirCallIdx++, param); RegisterOperand rparam = (RegisterOperand) param; + MIR_Call.setParam(s, mirCallIdx++, rparam); if (rparam.getType().isLongType()) { - MIR_Call.setParam(s, mirCallIdx++, L(regpool - .getSecondReg(rparam.getRegister()))); + rparam.setType(TypeReference.Int); + MIR_Call.setParam(s, mirCallIdx-1, rparam); + MIR_Call.setParam(s, mirCallIdx++, + new RegisterOperand(regpool.getSecondReg(rparam.getRegister()), TypeReference.Int)); } } else if (param instanceof LongConstantOperand) { LongConstantOperand val = (LongConstantOperand) param; @@ -3109,8 +3111,9 @@ // NOTE: longs passed little endian to C callee! RegisterOperand rparam = (RegisterOperand) param; if (rparam.getType().isLongType()) { - MIR_Call.setParam(s, mirCallIdx++, L(regpool - .getSecondReg(rparam.getRegister()))); + rparam.setType(TypeReference.Int); + MIR_Call.setParam(s, mirCallIdx++, + new RegisterOperand(regpool.getSecondReg(rparam.getRegister()), TypeReference.Int)); } MIR_Call.setParam(s, mirCallIdx++, param); } else if (param instanceof LongConstantOperand) { @@ -3188,8 +3191,10 @@ VM._assert((tc.getTrapCode() == RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO) && (((LongConstantOperand) v2).value == 0L)); } + RegisterOperand vr = v1.copyRO(); + vr.setType(TypeReference.Int); RegisterOperand rr = regpool.makeTempInt(); - EMIT(CPOS(s, MIR_Move.create(IA32_MOV, rr, v1.copy()))); + EMIT(CPOS(s, MIR_Move.create(IA32_MOV, rr, vr))); EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, rr.copy(), new RegisterOperand(regpool.getSecondReg(v1.getRegister()), TypeReference.Int)))); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ComplexLIR2MIRExpansion.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ComplexLIR2MIRExpansion.java 2008-09-30 22:47:54 UTC (rev 15028) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ComplexLIR2MIRExpansion.java 2008-09-30 23:01:03 UTC (rev 15029) @@ -252,6 +252,7 @@ // Move the maxlongFloat value and the value into x87 registers and compare and // branch if they are <= or unordered. RegisterOperand resultHi = Unary.getResult(s); + resultHi.setType(TypeReference.Int); RegisterOperand resultLo = new RegisterOperand(ir.regpool.getSecondReg(resultHi.getRegister()), TypeReference.Int); RegisterOperand value = Unary.getVal(s).asRegister(); @@ -430,6 +431,7 @@ // Move the maxlongFloat value and the value into x87 registers and compare and // branch if they are <= or unordered. RegisterOperand resultHi = Unary.getResult(s); + resultHi.setType(TypeReference.Int); RegisterOperand resultLo = new RegisterOperand(ir.regpool.getSecondReg(resultHi.getRegister()), TypeReference.Int); RegisterOperand value = Unary.getVal(s).asRegister(); @@ -924,6 +926,7 @@ Register xh = ((RegisterOperand) IfCmp.getVal1(s)).getRegister(); Register xl = ir.regpool.getSecondReg(xh); RegisterOperand yh = (RegisterOperand) IfCmp.getClearVal2(s); + yh.setType(TypeReference.Int); RegisterOperand yl = new RegisterOperand(ir.regpool.getSecondReg(yh.getRegister()), TypeReference.Int); basic_long_ifcmp(s, ir, cond, xh, xl, yh, yl); return nextInstr; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/CallingConvention.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/CallingConvention.java 2008-09-30 22:47:54 UTC (rev 15028) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/CallingConvention.java 2008-09-30 23:01:03 UTC (rev 15029) @@ -626,7 +626,7 @@ // the symbolic. First a move from the physical to a fresh temp // before start and second a move from the temp to the // 'real' parameter symbolic after start. - RegisterOperand tmp = ir.regpool.makeTemp(rType); + RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.Int); Register param = phys.getGPRParam(gprIndex); RegisterOperand pOp = new RegisterOperand(param, rType); start.insertBefore(PhysicalRegisterTools.makeMoveInstruction(tmp, pOp)); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/StackManager.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/StackManager.java 2008-09-30 22:47:54 UTC (rev 15028) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/StackManager.java 2008-09-30 23:01:03 UTC (rev 15029) @@ -680,9 +680,10 @@ int location = RegisterAllocatorState.getSpill(symb.getRegister()); // Create a memory operand M representing the spill location. - Operand M = null; - int type = PhysicalRegisterSet.getPhysicalRegisterType(symb.getRegister()); - int size = PhysicalRegisterSet.getSpillSize(type); + int size = symb.getType().getMemoryBytes(); + if (size < 4) + size = 4; + StackLocationOperand M = new StackLocationOperand(true, -location, (byte) size); M = new StackLocationOperand(true, -location, (byte) size); Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-09-30 22:47:54 UTC (rev 15028) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-09-30 23:01:03 UTC (rev 15029) @@ -1952,6 +1952,7 @@ EMIT_INSTRUCTION RegisterOperand hres = Load.getResult(P(p)); \\ RegisterOperand lres = new RegisterOperand(regpool.getSecondReg(hres.getRegister()), TypeReference.Int); \\ +hres.setType(TypeReference.Int); \\ EMIT(CPOS(P(p), MIR_Move.create(IA32_MOV, hres, MO_L(P(p), DW, DW).copy()))); \\ EMIT(MIR_Move.mutate(P(p), IA32_MOV, lres, MO_L(P(p), DW))); @@ -1963,6 +1964,7 @@ EMIT_INSTRUCTION RegisterOperand hres = ALoad.getResult(P(p)); \\ RegisterOperand lres = new RegisterOperand(regpool.getSecondReg(hres.getRegister()), TypeReference.Int); \\ +hres.setType(TypeReference.Int); \\ EMIT(CPOS(P(p), MIR_Move.create(IA32_MOV, hres, MO_AL(P(p), QW_S, DW, DW).copy()))); \\ EMIT(MIR_Move.mutate(P(p), IA32_MOV, lres, MO_AL(P(p), QW_S, DW))); @@ -2025,6 +2027,7 @@ 30 EMIT_INSTRUCTION RegisterOperand hres = Prepare.getResult(P(p)); \\ +hres.setType(TypeReference.Int); \\ MemoryOperand hmo = MO(Prepare.getAddress(P(p)), Prepare.getOffset(P(p)), DW, \\ Prepare.getLocation(P(p)), Prepare.getGuard(P(p)), DW); \\ RegisterOperand lres = new RegisterOperand(regpool.getSecondReg(hres.getRegister()), TypeReference.Int); \\ @@ -2349,6 +2352,7 @@ 30 EMIT_INSTRUCTION RegisterOperand hval = (RegisterOperand)Store.getValue(P(p)); \\ +hval.setType(TypeReference.Int); \\ RegisterOperand lval = new RegisterOperand(regpool.getSecondReg(hval.getRegister()), TypeReference.Int); \\ EMIT(CPOS(P(p), MIR_Move.create(IA32_MOV, MO_S(P(p), DW, DW).copy(), hval))); \\ EMIT(MIR_Move.mutate(P(p), IA32_MOV, MO_S(P(p), DW), lval)); @@ -2367,6 +2371,7 @@ 30 EMIT_INSTRUCTION RegisterOperand hval = (RegisterOperand)AStore.getValue(P(p)); \\ +hval.setType(TypeReference.Int); \\ RegisterOperand lval = new RegisterOperand(regpool.getSecondReg(hval.getRegister()), TypeReference.Int); \\ EMIT(CPOS(P(p), MIR_Move.create(IA32_MOV, MO_AS(P(p), QW_S, DW, DW).copy(), hval))); \\ EMIT(MIR_Move.mutate(P(p), IA32_MOV, MO_AS(P(p), QW_S, DW), lval)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-02 22:17:25
|
Revision: 15045 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15045&view=rev Author: captain5050 Date: 2008-10-02 22:16:59 +0000 (Thu, 02 Oct 2008) Log Message: ----------- RVM-667 and RVM-668 WIP. Modify tableswitch implementation to ensure call-return pairing and to enable RIP optimization on x86 64. Similar pairing for baseline jsr-ret. Various fixes and improvements to Intel assembler for x86 64. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/assembler/ia32/Lister.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/FinalMIRExpansion.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java rvmroot/trunk/rvm/src/org/jikesrvm/ia32/OutOfLineMachineCode.java rvmroot/trunk/rvm/src/org/jikesrvm/ia32/RegisterConstants.java rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/GenerateAssembler.java rvmroot/trunk/rvm/src-generated/opt-ir/ia32/InstructionFormatList.dat rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -2215,7 +2215,11 @@ @Override protected final void emit_ret(int index) { Offset offset = localOffset(index); - asm.emitJMP_RegDisp(ESP, offset); + // Can be: + // asm.emitJMP_RegDisp(ESP, offset); + // but this will cause call-return branch prediction pairing to fail + asm.emitPUSH_RegDisp(ESP, offset); + asm.emitRET(); } /** @@ -2229,9 +2233,9 @@ int bTarget = biStart + defaultval; int mTarget = bytecodeMap[bTarget]; int n = high - low + 1; // n = number of normal cases (0..n-1) - asm.emitPOP_Reg(T0); // T0 is index of desired case - asm.emitSUB_Reg_Imm(T0, low); // relativize T0 - asm.emitCMP_Reg_Imm(T0, n); // 0 <= relative index < n + asm.emitPOP_Reg(T1); // T1 is index of desired case + asm.emitSUB_Reg_Imm(T1, low); // relativize T1 + asm.emitCMP_Reg_Imm(T1, n); // 0 <= relative index < n if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) { int firstCounter = edgeCounterIdx; @@ -2244,30 +2248,34 @@ fr.resolve(asm); // Increment counter for the appropriate case - incEdgeCounterIdx(S0, T0, firstCounter); + incEdgeCounterIdx(S0, T1, firstCounter); } else { asm.emitJCC_Cond_ImmOrLabel(Assembler.LGE, mTarget, bTarget); // if not, goto default case } - // make table aligned if doing alignment checking - if (VM.AlignmentChecking) { - asm.emitNOP((asm.getMachineCodeIndex() + 1) & 3); + // T0 = EIP at start of method + asm.emitMETHODSTART_Reg(T0); + // T0 += [T0 + T1<<2 + ??] - we will patch ?? when we know the placement of the table + int toPatchAddress = asm.getMachineCodeIndex(); + if (VM.buildFor32Addr()) { + asm.emitMOV_Reg_RegIdx(T1, T0, T1, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE)); + asm.emitADD_Reg_Reg(T0, T1); + } else { + asm.emitMOV_Reg_RegIdx(T1, T0, T1, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE)); + asm.emitADD_Reg_Reg_Quad(T0, T1); } - - asm.emitCALL_Imm(asm.getMachineCodeIndex() + 5 + (n << LG_WORDSIZE)); - // jump around table, pushing address of 0th delta - for (int i = 0; i < n; i++) { // create table of deltas + // JMP T0 + asm.emitJMP_Reg(T0); + asm.emitNOP((4-asm.getMachineCodeIndex()) & 3); // align table + // create table of offsets from start of method + asm.patchSwitchTableDisplacement(toPatchAddress); + for (int i = 0; i < n; i++) { int offset = bcodes.getTableSwitchOffset(i); bTarget = biStart + offset; mTarget = bytecodeMap[bTarget]; - // delta i: difference between address of case i and of delta 0 asm.emitOFFSET_Imm_ImmOrLabel(i, mTarget, bTarget); } bcodes.skipTableSwitchOffsets(n); - asm.emitPOP_Reg(S0); // S0 = address of 0th delta - asm.emitADD_Reg_RegIdx(S0, S0, T0, Assembler.WORD, NO_SLOT); // S0 += [S0 + T0<<2] - asm.emitPUSH_Reg(S0); // push computed case address - asm.emitRET(); // goto case } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineMagic.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -883,8 +883,8 @@ */ private static final class Prefetch extends MagicGenerator { void generateMagic(Assembler asm, MethodReference m, RVMMethod cm, Offset sd) { - asm.emitPOP_Reg(T0); - asm.emitPREFETCHNTA_Reg(T0); + asm.emitPOP_Reg(EDI); + asm.emitPREFETCHNTA_RegInd(EDI); } } static { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/assembler/ia32/Lister.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/assembler/ia32/Lister.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/assembler/ia32/Lister.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -77,21 +77,21 @@ end(i); } - public void RI(int i, String op, MachineRegister R0, int n) { + public void RI(int i, String op, MachineRegister R0, long n) { i = begin(i, op); VM.sysWrite(right(R0 + " ", DEST_AREA_SIZE)); VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); end(i); } - public void RDI(int i, String op, MachineRegister R0, Offset d, int n) { + public void RDI(int i, String op, MachineRegister R0, Offset d, long n) { i = begin(i, op); VM.sysWrite(right(decimal(d) + "[" + R0 + "]", DEST_AREA_SIZE)); VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); end(i); } - public void RNI(int i, String op, MachineRegister R0, int n) { + public void RNI(int i, String op, MachineRegister R0, long n) { i = begin(i, op); VM.sysWrite(right("[" + R0 + "]", DEST_AREA_SIZE)); VM.sysWrite(right(decimal(n) + " ", SOURCE_AREA_SIZE)); @@ -164,7 +164,7 @@ end(i); } - public void RXDI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, int n) { + public void RXDI(int i, String op, MachineRegister R0, MachineRegister X, short s, Offset d, long n) { i = begin(i, op); VM.sysWrite(right("[" + decimal(d) + "+" + R0 + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE)); @@ -186,14 +186,14 @@ end(i); } - public void RFDI(int i, String op, MachineRegister X, short s, Offset d, int n) { + public void RFDI(int i, String op, MachineRegister X, short s, Offset d, long n) { i = begin(i, op); VM.sysWrite(right("[" + decimal(d) + "+" + X + "<<" + decimal(s) + "]", DEST_AREA_SIZE)); VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE)); end(i); } - public void RAI(int i, String op, Address d, int n) { + public void RAI(int i, String op, Address d, long n) { i = begin(i, op); VM.sysWrite(right("[" + hex(d) + "]", DEST_AREA_SIZE)); VM.sysWrite(right(decimal(n), SOURCE_AREA_SIZE)); @@ -407,6 +407,41 @@ return (sign + result); } + @Pure + static String decimal(long n) { + if (n == 0) return "0"; + String sign = ""; + if (n < 0) { + sign = "-"; + n = -n; + } + String result = ""; + while (0 < n) { + long i = n % 10; + n /= 10; + if (i == 0) { + result = "0" + result; + } else if (i == 1) { + result = "1" + result; + } else if (i == 2) { + result = "2" + result; + } else if (i == 3) { + result = "3" + result; + } else if (i == 4) { + result = "4" + result; + } else if (i == 5) { + result = "5" + result; + } else if (i == 6) { + result = "6" + result; + } else if (i == 7) { + result = "7" + result; + } else if (i == 8) { + result = "8" + result; + } else if (i == 9) result = "9" + result; + } + return (sign + result); + } + private static String decimal(short s) { return decimal((int) s); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -458,7 +458,7 @@ LookupSwitch.setTarget(l, i, TableSwitch.getClearTarget(s, i)); LookupSwitch.setBranchProfile(l, i, TableSwitch.getClearBranchProfile(s, i)); } - s.insertAfter(l); + s.insertAfter(CPOS(s, l)); return s.remove(); } RegisterOperand reg = val.asRegister(); @@ -474,13 +474,13 @@ t = reg.copyU2U(); } BranchProfileOperand defaultProb = TableSwitch.getClearDefaultBranchProfile(s); - s.replace(IfCmp.create(INT_IFCMP, - ir.regpool.makeTempValidation(), - t, - IC(highLimit - lowLimit), - ConditionOperand.HIGHER(), - defaultLabel, - defaultProb)); + s.replace(CPOS(s, IfCmp.create(INT_IFCMP, + ir.regpool.makeTempValidation(), + t, + IC(highLimit - lowLimit), + ConditionOperand.HIGHER(), + defaultLabel, + defaultProb))); // Reweight branches to account for the default branch going. If // the default probability was ALWAYS then when we recompute the // weight to be a proportion of the total number of branches. @@ -488,7 +488,7 @@ final float weight = defaultIsAlways ? 1f / number : 1f / (1f - defaultProb.takenProbability); /********** second Basic Block ******/ - s2 = LowTableSwitch.create(LOWTABLESWITCH, t.copyRO(), number * 2); + s2 = CPOS(s, LowTableSwitch.create(LOWTABLESWITCH, t.copyRO(), number * 2)); boolean containsDefault = false; for (int i = 0; i < number; i++) { BranchOperand b = TableSwitch.getClearTarget(s, i); @@ -516,7 +516,7 @@ // then just use a GOTO instead of the LOWTABLESWITCH. // This actually happens (very occasionally), and is easy to test for. if (BB2.getNumberOfNormalOut() == 1) { - BB2.appendInstruction(Goto.create(GOTO, LowTableSwitch.getTarget(s2, 0))); + BB2.appendInstruction(CPOS(s, Goto.create(GOTO, LowTableSwitch.getTarget(s2, 0)))); } else { BB2.appendInstruction(s2); } @@ -1020,7 +1020,7 @@ public static RegisterOperand insertBinary(Instruction s, IR ir, Operator operator, TypeReference type, Operand o1, Operand o2) { RegisterOperand t = ir.regpool.makeTemp(type); - s.insertBefore(Binary.create(operator, t, o1, o2)); + s.insertBefore(CPOS(s, Binary.create(operator, t, o1, o2))); return t.copyD2U(); } @@ -1036,7 +1036,7 @@ static RegisterOperand InsertUnary(Instruction s, IR ir, Operator operator, TypeReference type, Operand o1) { RegisterOperand t = ir.regpool.makeTemp(type); - s.insertBefore(Unary.create(operator, t, o1)); + s.insertBefore(CPOS(s, Unary.create(operator, t, o1))); return t.copyD2U(); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -80,6 +80,7 @@ import static org.jikesrvm.compilers.opt.ir.Operators.IA32_LEA; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_LOCK_CMPXCHG; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_LOCK_CMPXCHG8B; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_METHODSTART; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOV; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOVD; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOVLPD; @@ -3144,8 +3145,10 @@ // going to get into trouble (if someone else was also using index). RegisterOperand newIndex = regpool.makeTempInt(); EMIT(CPOS(s, MIR_Move.create(IA32_MOV, newIndex, LowTableSwitch.getIndex(s)))); + RegisterOperand methodStart = regpool.makeTemp(TypeReference.Address); + EMIT(CPOS(s, MIR_Nullary.create(IA32_METHODSTART, methodStart))); int number = LowTableSwitch.getNumberOfTargets(s); - Instruction s2 = CPOS(s, MIR_LowTableSwitch.create(MIR_LOWTABLESWITCH, newIndex.copyRO(), number * 2)); + Instruction s2 = CPOS(s, MIR_LowTableSwitch.create(MIR_LOWTABLESWITCH, newIndex.copyRO(), methodStart.copyD2U(), number * 2)); for (int i = 0; i < number; i++) { MIR_LowTableSwitch.setTarget(s2, i, LowTableSwitch.getTarget(s, i)); MIR_LowTableSwitch.setBranchProfile(s2, i, LowTableSwitch Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -26,6 +26,7 @@ import org.jikesrvm.compilers.opt.ir.MIR_Compare; import org.jikesrvm.compilers.opt.ir.MIR_CondBranch; import org.jikesrvm.compilers.opt.ir.MIR_Lea; +import org.jikesrvm.compilers.opt.ir.MIR_LowTableSwitch; import org.jikesrvm.compilers.opt.ir.MIR_Move; import org.jikesrvm.compilers.opt.ir.MIR_Test; import org.jikesrvm.compilers.opt.ir.MIR_Unary; @@ -675,6 +676,8 @@ // these generate no code return 0; } + case IA32_METHODSTART_opcode: + return 12; // Generated from the same case in Assembler case IA32_ADC_opcode: case IA32_ADD_opcode: @@ -704,6 +707,7 @@ case IA32_MULSD_opcode: case IA32_DIVSD_opcode: case IA32_XORPD_opcode: + case IA32_SQRTSD_opcode: case IA32_ADDSS_opcode: case IA32_SUBSS_opcode: case IA32_MULSS_opcode: @@ -763,6 +767,7 @@ return size; } case IA32_MOVD_opcode: + case IA32_MOVLPD_opcode: case IA32_MOVQ_opcode: case IA32_MOVSS_opcode: case IA32_MOVSD_opcode: { @@ -803,6 +808,8 @@ size += operandCost(value, false); return size; } + case MIR_LOWTABLESWITCH_opcode: + return MIR_LowTableSwitch.getNumberOfTargets(inst)*4 + 13; case IA32_OFFSET_opcode: return 4; case IA32_JCC_opcode: @@ -811,7 +818,7 @@ case IA32_LOCK_opcode: return 1; case IG_PATCH_POINT_opcode: - return 6; + return 8; case IA32_INT_opcode: return 2; case IA32_RET_opcode: @@ -932,7 +939,7 @@ } /** - * Emit the given instruction, assuming that + * Emit the given instruction, assuming that * it is a MIR_Branch instruction * and has a JMP operator * @@ -979,6 +986,37 @@ } /** + * Emit the given instruction, assuming that + * it is a MIR_LowTableSwitch instruction + * and has a MIR_LOWTABLESWITCH operator + * + * @param inst the instruction to assemble + */ + protected void doLOWTABLESWITCH(Instruction inst) { + int n = MIR_LowTableSwitch.getNumberOfTargets(inst); // n = number of normal cases (0..n-1) + GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number); + GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number); + // idx += [ms + idx<<2 + ??] - we will patch ?? when we know the placement of the table + int toPatchAddress = getMachineCodeIndex(); + if (VM.buildFor32Addr()) { + emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE)); + emitADD_Reg_Reg(idx, ms); + } else { + emitMOV_Reg_RegIdx(idx, ms, idx, Assembler.WORD, Offset.fromIntZeroExtend(Integer.MAX_VALUE)); + emitADD_Reg_Reg_Quad(idx, ms); + } + // JMP T0 + emitJMP_Reg(idx); + emitNOP((4-getMachineCodeIndex()) & 3); // align table + // create table of offsets from start of method + patchSwitchTableDisplacement(toPatchAddress); + for (int i = 0; i < n; i++) { + Operand target = MIR_LowTableSwitch.getTarget(inst, i); + emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target)); + } + } + + /** * Debugging support (return a printable representation of the machine code). * * @param instr An integer to be interpreted as a PowerPC instruction Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/FinalMIRExpansion.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/FinalMIRExpansion.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/FinalMIRExpansion.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -14,22 +14,18 @@ import org.jikesrvm.VM; import org.jikesrvm.classloader.RVMMethod; -import org.jikesrvm.classloader.TypeReference; import org.jikesrvm.compilers.opt.ir.BBend; import org.jikesrvm.compilers.opt.ir.Label; import org.jikesrvm.compilers.opt.ir.MIR_BinaryAcc; import org.jikesrvm.compilers.opt.ir.MIR_Branch; import org.jikesrvm.compilers.opt.ir.MIR_Call; -import org.jikesrvm.compilers.opt.ir.MIR_CaseLabel; import org.jikesrvm.compilers.opt.ir.MIR_Compare; import org.jikesrvm.compilers.opt.ir.MIR_CondBranch; import org.jikesrvm.compilers.opt.ir.MIR_CondBranch2; import org.jikesrvm.compilers.opt.ir.MIR_Empty; import org.jikesrvm.compilers.opt.ir.MIR_Lea; -import org.jikesrvm.compilers.opt.ir.MIR_LowTableSwitch; import org.jikesrvm.compilers.opt.ir.MIR_Move; import org.jikesrvm.compilers.opt.ir.MIR_Nullary; -import org.jikesrvm.compilers.opt.ir.MIR_Return; import org.jikesrvm.compilers.opt.ir.MIR_Set; import org.jikesrvm.compilers.opt.ir.MIR_Test; import org.jikesrvm.compilers.opt.ir.MIR_Trap; @@ -73,15 +69,12 @@ import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOV; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOV_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_MOVZX__B; -import static org.jikesrvm.compilers.opt.ir.Operators.IA32_OFFSET; -import static org.jikesrvm.compilers.opt.ir.Operators.IA32_RET; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_SET__B_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_SHL; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_TEST_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_TRAPIF; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_TRAPIF_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_XOR; -import static org.jikesrvm.compilers.opt.ir.Operators.MIR_LOWTABLESWITCH_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.NULL_CHECK_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.REQUIRE_ESP_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.YIELDPOINT_BACKEDGE_opcode; @@ -134,55 +127,6 @@ p.scratchObject = null; switch (p.getOpcode()) { - case MIR_LOWTABLESWITCH_opcode: { - // split the basic block after the MIR_LOWTABLESWITCH - BasicBlock thisBlock = p.getBasicBlock(); - BasicBlock nextBlock = thisBlock.splitNodeWithLinksAt(p, ir); - nextBlock.firstInstruction().setmcOffset(-1); - - // place offset data table after call so that call pushes - // the base address of this table onto the stack - int NumTargets = MIR_LowTableSwitch.getNumberOfTargets(p); - for (int i = 0; i < NumTargets; i++) { - thisBlock.appendInstruction(MIR_CaseLabel.create(IA32_OFFSET, - IC(i), - MIR_LowTableSwitch.getClearTarget(p, i))); - } - // calculate address to which to jump, and store it - // on the top of the stack - Register regS = MIR_LowTableSwitch.getIndex(p).getRegister(); - nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_SHL, - new RegisterOperand(regS, TypeReference.Int), - IC(2))); - nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD, - new RegisterOperand(regS, TypeReference.Int), - MemoryOperand.I(new RegisterOperand(phys.getESP(), - TypeReference.Int), - (byte) 4, - null, - null))); - nextBlock.appendInstruction(MIR_Move.create(IA32_MOV, - new RegisterOperand(regS, TypeReference.Int), - MemoryOperand.I(new RegisterOperand(regS, - TypeReference.Int), - (byte) 4, - null, - null))); - nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD, - MemoryOperand.I(new RegisterOperand(phys.getESP(), - TypeReference.Int), - (byte) 4, - null, - null), - new RegisterOperand(regS, TypeReference.Int))); - // ``return'' to mangled return address - nextBlock.appendInstruction(MIR_Return.create(IA32_RET, IC(0), null, null)); - - // CALL next block to push pc of next ``instruction'' onto stack - MIR_Call.mutate0(p, IA32_CALL, null, null, nextBlock.makeJumpTarget(), null); - } - break; - case IA32_TEST_opcode: // don't bother telling rest of compiler that memory operand // must be first; we can just commute it here. Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -91,8 +91,10 @@ // handle special cases switch (s.getOpcode()) { case MIR_LOWTABLESWITCH_opcode: { - RegisterOperand op = MIR_LowTableSwitch.getIndex(s); + RegisterOperand op = MIR_LowTableSwitch.getMethodStart(s); noteMustNotSpill(op.getRegister()); + op = MIR_LowTableSwitch.getIndex(s); + noteMustNotSpill(op.getRegister()); } break; case IA32_MOVZX__B_opcode: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/ia32/OutOfLineMachineCode.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/ia32/OutOfLineMachineCode.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/ia32/OutOfLineMachineCode.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -14,10 +14,12 @@ import org.jikesrvm.ArchitectureSpecific; import org.jikesrvm.VM; +import org.jikesrvm.classloader.RVMField; import org.jikesrvm.compilers.common.assembler.ForwardReference; import org.jikesrvm.compilers.common.assembler.ia32.Assembler; import org.jikesrvm.objectmodel.ObjectModel; import org.jikesrvm.runtime.ArchEntrypoints; +import org.jikesrvm.runtime.EntrypointHelper; import org.jikesrvm.runtime.Entrypoints; import org.vmmagic.unboxed.Offset; @@ -48,6 +50,7 @@ //-----------// public static void init() { + generatePcThunkInstructions(); reflectiveMethodInvokerInstructions = generateReflectiveMethodInvokerInstructions(); saveThreadStateInstructions = generateSaveThreadStateInstructions(); threadSwitchInstructions = generateThreadSwitchInstructions(); @@ -58,7 +61,37 @@ // implementation // //----------------// + public static final RVMField[] pcThunkInstructionsField = new RVMField[8]; + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkEAXInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkEBXInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkECXInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkEDXInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkEBPInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkESIInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) + // Accessed via field array above + private static ArchitectureSpecific.CodeArray pcThunkEDIInstructions; + + @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) // Accessed via EntryPoints private static ArchitectureSpecific.CodeArray reflectiveMethodInvokerInstructions; @SuppressWarnings({"unused", "UnusedDeclaration", "FieldCanBeLocal"}) @@ -78,6 +111,70 @@ private static final Offset CODE_FP_OFFSET = Offset.fromIntSignExtend(WORDSIZE * 6); /** + * Machine code to get the address of the instruction after the call to this + * method + */ + private static void generatePcThunkInstructions() { + Assembler asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(EAX, SP); + asm.emitRET(); + pcThunkEAXInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[EAX.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkEAXInstructions", ArchitectureSpecific.CodeArray.class); + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(EBX, SP); + asm.emitRET(); + pcThunkEBXInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[EBX.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkEBXInstructions", ArchitectureSpecific.CodeArray.class); + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(ECX, SP); + asm.emitRET(); + pcThunkECXInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[ECX.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkECXInstructions", ArchitectureSpecific.CodeArray.class); + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(EDX, SP); + asm.emitRET(); + pcThunkEDXInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[EDX.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkEDXInstructions", ArchitectureSpecific.CodeArray.class); + + // NB a PC thunk into ESP isn't allowed + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(EBP, SP); + asm.emitRET(); + pcThunkEBPInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[EBP.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkEBPInstructions", ArchitectureSpecific.CodeArray.class); + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(ESI, SP); + asm.emitRET(); + pcThunkESIInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[ESI.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkESIInstructions", ArchitectureSpecific.CodeArray.class); + + asm = new ArchitectureSpecific.Assembler(0); + asm.emitMOV_Reg_RegInd(EDI, SP); + asm.emitRET(); + pcThunkEDIInstructions = asm.getMachineCodes(); + pcThunkInstructionsField[EDI.value()] = + EntrypointHelper.getField(OutOfLineMachineCode.class, + "pcThunkEDIInstructions", ArchitectureSpecific.CodeArray.class); + } + + /** * Machine code for reflective method invocation. * * VM compiled with NUM_PARAMETERS_GPRS == 0 Modified: rvmroot/trunk/rvm/src/org/jikesrvm/ia32/RegisterConstants.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/ia32/RegisterConstants.java 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src/org/jikesrvm/ia32/RegisterConstants.java 2008-10-02 22:16:59 UTC (rev 15045) @@ -39,7 +39,8 @@ */ public enum GPR implements MachineRegister { EAX(0), ECX(1), EDX(2), EBX(3), ESP(4), EBP(5), ESI(6), EDI(7), - R8(8), R9(9), R10(10), R11(11), R12(12), R13(13), R14(14), R15(15); + R8(8), R9(9), R10(10), R11(11), R12(12), R13(13), R14(14), R15(15), + EIP(16); /** Local copy of the backing array. Copied here to avoid calls to clone */ private static final GPR[] vals = values(); @@ -54,11 +55,20 @@ @UninterruptibleNoWarn("Interruptible code only called during boot image creation") @Pure public byte value() { + byte result; if (!org.jikesrvm.VM.runningVM) { - return (byte)ordinal(); + result = (byte)ordinal(); } else { - return (byte)java.lang.JikesRVMSupport.getEnumOrdinal(this); + result = (byte)java.lang.JikesRVMSupport.getEnumOrdinal(this); } + if (VM.VerifyAssertions) { + if (VM.buildFor32Addr()) { + VM._assert(result >=0 && result <= 7); + } else { + VM._assert(result >=0 && result <= 15); + } + } + return result; } /** @return does this register require a REX prefix byte? */ @Pure Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-10-02 22:07:07 UTC (rev 15044) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-10-02 22:16:59 UTC (rev 15045) @@ -15,6 +15,7 @@ import org.jikesrvm.*; import org.jikesrvm.runtime.Magic; import org.jikesrvm.compilers.baseline.ia32.BaselineCompilerImpl; +import org.jikesrvm.ia32.OutOfLineMachineCode; import org.jikesrvm.ia32.RegisterConstants; import org.jikesrvm.compilers.common.assembler.ForwardReference; import org.jikesrvm.compilers.common.assembler.AbstractAssembler; @@ -672,14 +673,19 @@ /** * Generate the appropriate bytes into the generated code to denote - * an absolute-addresss--register instruction. + * an absolute-address--register instruction. * * @param disp the displacement for the r/m operand * @param reg2 the other operand or the extended opcode */ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) private void emitAbsRegOperands(Address disp, MachineRegister reg2) { - setMachineCodes(mi++, regIndirectRegModRM(EBP, reg2)); + if (VM.buildFor32Addr()) { + setMachineCodes(mi++, regIndirectRegModRM(EBP, reg2)); // EBP == No displacement + } else { + setMachineCodes(mi++, regIndirectRegModRM(ESP, reg2)); // ESP == SIB byte + setMachineCodes(mi++, sib((short)0, EBP, ESP)); // EBP+ESP<<0 == no SIB + } emitImm32(disp); } @@ -758,9 +764,20 @@ } /** - * Generate the smallest-byte-first IA32 encoding of 16 bit - * immediates into the generated code. + * Generate the smallest-byte first x86_64 encoding of the 64 bit + * immeditate into the generated code. * + * @param imm the immediate the generate; + */ + @Inline + private void emitImm64(long imm) { + mi = emitImm64(imm, mi); + } + + /** + * Generate the IA32 encoding of an 16 bit immediate into the + * generated code. + * * @param imm the immediate to generate. */ @Inline @@ -795,7 +812,7 @@ /** * Generate the smallest-byte-first IA32 encoding of 32 bit - * immediates into the generated code at the location specified. + * immediate into the generated code at the location specified. * * @param imm the immediate to generate. * @param idx the location in the generated code to write. @@ -810,6 +827,25 @@ } /** + * Generate the smallest-byte first x86_64 encoding of the 64 bit + * immeditate into the generated code at the location specified. + * + * @param imm the immediate the generate; + * @param idx the location in the generated code to write. + */ + private int emitImm64(long imm, int idx) { + setMachineCodes(idx++, (byte) ((imm >> 0) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 8) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 16) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 24) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 32) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 40) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 48) & 0xFF)); + setMachineCodes(idx++, (byte) ((imm >> 56) & 0xFF)); + return idx; + } + + /** * Generate the IA32 encoding of an 8 bit immediate into the * generated code at the location specified. * @@ -868,9 +904,9 @@ /** * Generate a patch point into the generated code. - * (1) force patch point to be 16 bit aligned by optionally + * (1) force patch point to be 32 bit aligned by optionally * generating a nop. - * (2) emit a short branch (2 byte) around 3 bytes of nops. + * (2) emit a short branch (2 byte) around 3 bytes of nop. * (3) If the the code is later patched, we first patch the 3 * nop bytes to be the upper 24 bits of a long jump * instruction, then update the 2 bytes of the patch @@ -878,13 +914,9 @@ */ @Inline public final void emitPatchPoint() { - if ((mi & 0x1) == 1) { - emitNOP(1); - } + emitNOP((4-mi-1) & 3); ForwardReference r = forwardJMP(); - emitNOP(1); - emitNOP(1); - emitNOP(1); + emitNOP(3); r.resolve(this); } @@ -1029,9 +1061,9 @@ } /** - * Set up a code sequence to push a return address. This involves pushing the + * Set up a code sequence to push a return address. This involves pushing the * current instruction address, and setting up an ADD that gets resolved later. - * + * * @param bReturn the return address that is to be loaded. */ public final void generateLoadReturnAddress(int bReturn) { @@ -1042,7 +1074,7 @@ /* Fake MAX_INTEGER to ensure 32 bit immediate */ emitADD_RegInd_Imm(ESP, Integer.MAX_VALUE); } - + /** * Patch the code sequence at sourceIndex to load the complete instruction address * of the current instruction. @@ -1059,6 +1091,24 @@ } /** + * Generate a code sequence that will place the address of the start of the + * method in destReg + * + * @param destReg register to hold address of start of method + */ + public final void emitMETHODSTART_Reg(GPR destReg) { + if (VM.buildFor32Addr()) { + Offset pcThunkOffset; + pcThunkOffset = OutOfLineMachineCode.pcThunkInstructionsField[destReg.value()].getOffset(); + emitCALL_Abs(Magic.getTocPointer().plus(pcThunkOffset)); + emitADD_Reg_Imm(destReg, -mi); + } else { + emitLEA_Reg_RegDisp_Quad(destReg, GPR.EIP, Offset.fromIntZeroExtend(Integer.MAX_VALUE)); + emitImm32(-mi, mi-4); + } + } + + /** * Make a forward reference and emit a long JMP * @param btarget optional * @return a forward reference for patching later @@ -1140,48 +1190,31 @@ ///////////////////////////////////// /** - * <P> An OFFSET instruction is not really an instruction; it is rather + * An OFFSET instruction is not really an instruction; it is rather * an address (of an instruction) that is written into the binary * code. These are used to build a table of addresses for table - * switches. The code for tableswitches first captures the current - * pc, then jumps to that value plus the value from a table of - * relative offsets indexed by the value of the switch expression. </P> + * switches. The code for tableswitches first calculates the address of the + * start of the method. Using this address a branch relative to the start + * of the method is computed by loading the offset from the start of the + * method for a particular switch case. The OFFSET instruction is encoding + * one value in the table. * - * <P> This mechanism assumes code for emitting tableswitch looks as - * follows; it is not very nice, but no relocatable IA32 code for such - * switches is. Indeed, GCC generates something similar when given - * -fpic. Note that default cases must be handled separateky. </P> + * This mechanism assumes code for emitting tableswitch looks as + * follows; it is not very nice, but is improved on X86 64 with the addition + * of RIP displacement addressing. The GNU tools generate something. + * Note that default cases must be handled separately. </P> * * <PRE> - * CALL x ([SP] gets IP of first OFFSET instruction) + * T0 = getPCThunk() or RIP less offset from start of method + * T0 += [T0 + m<<2 + tableDisplacement] + * JMP T0 + * tableDisplacement: * OFFSET 0 (case 0 target) * OFFSET 1 (case 1 target) * ... * OFFSET n (case n target) - * - * ------------------------------- - * - * x: [SP] = [SP] + [ [SP] + case expression value<<2 ] - * RET (goes to adjusted location in [SP]) * </PRE> * - * <P> The above mechanism means that the RET instruction is - * effectively a register-indexed relative jump (the whole reason - * for this mess is that IA32 has no such instruction). The offset - * is based on the case expression, and the jump is relative to the - * instruction following the CALL. Thus, table offsets must be - * relative to the start of the table, not their own addresses - * within it. </P> - * - * <P> Therefore, handling of forward bracnhes is slightly different - * from the normal case of JMP and Jcc; when a forward branch is - * found, the current table entry (c) is stored into the table. - * When the fixup code runs, it uses this index to compute the - * start of the table, and store the offset of the target - * instruction relative to that. Similarly, for backward branches, - * the case index c is used to find the start of the table to store - * te appropriate relative offset. </P> - * * @see #patchSwitchCase * * @param c the table entry being emitted (i.e. the value of the @@ -1192,8 +1225,7 @@ public final void emitOFFSET_Imm_ImmOrLabel(int c, int mTarget, int bTarget) { int miStart = mi; if (0 < mTarget) { // resolved (backward) reference - int delta = mTarget - (mi - (c<<2)); // delta is from start of table of 4-byte entries (not this entry) - emitImm32(delta); + emitImm32(mTarget); if (lister != null) lister.I(miStart, "DATA", mTarget); } else { // unresolved forward reference ForwardReference r = new ForwardReference.SwitchCase(mi, bTarget); @@ -1206,7 +1238,7 @@ /** * Patch a tableswitch offset table entry at the given source * index. This method resolves the table entry at the given source - * index to point to the current instruction. + * index to point to the current instruction plus an aligning NOP. * * @see #emitOFFSET_Imm_ImmOrLabel * @@ -1223,13 +1255,27 @@ c |= (machineCodes[sourceIndex+1] & 0xFF) << 8; c |= (machineCodes[sourceIndex+2] & 0xFF) << 16; c |= (machineCodes[sourceIndex+3] & 0xFF) << 24; // c = case index - int delta = mi - (sourceIndex - (c<<2)); // from begining of table of 4-byte entries to here - setMachineCodes(sourceIndex+0, (byte) ((delta >> 0) & 0xFF)); - setMachineCodes(sourceIndex+1, (byte) ((delta >> 8) & 0xFF)); - setMachineCodes(sourceIndex+2, (byte) ((delta >> 16) & 0xFF)); - setMachineCodes(sourceIndex+3, (byte) ((delta >> 24) & 0xFF)); + emitImm32(mi, sourceIndex); // write mi to sourceIndex } + /** + * Patch the instruction that will load the displacement to the offset table + * from the start of the method assuming that the next code to be created is + * the offset table. + * + * @param toPatchAddress the address of the instruction that performs the + * displacement load + */ + public final void patchSwitchTableDisplacement(int toPatchAddress) { + if (VM.buildFor32Addr()) { + // the instruction to patch is an reg = [reg + idx<<scale + disp] + emitImm32(mi, toPatchAddress+3); + } else { + // the instruction to patch is an reg = [reg + idx<<scale + disp] + emitImm32(mi, toPatchAddress+3); + } + } + ///////////////////////////////////// // instructions (hand coded) // ///////////////////////////////////// @@ -1277,6 +1323,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) public final void emitCMOV_Cond_Reg_Reg(byte cond, GPR dst, GPR src) { int miStart = mi; + generateREXprefix(false, dst, null, src); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitRegRegOperands(src, dst); @@ -1292,6 +1339,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) public final void emitCMOV_Cond_Reg_RegDisp(byte cond, GPR dst, GPR src, Offset disp) { int miStart = mi; + generateREXprefix(false, dst, null, src); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitRegDispRegOperands(src, disp, dst); @@ -1307,6 +1355,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) public final void emitCMOV_Cond_Reg_RegInd(byte cond, GPR dst, GPR src) { int miStart = mi; + generateREXprefix(false, dst, null, src); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitRegIndirectRegOperands(src, dst); @@ -1322,6 +1371,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) public final void emitCMOV_Cond_Reg_RegOff(byte cond, GPR dst, GPR index2, short scale2, Offset disp2) { int miStart = mi; + generateREXprefix(false, dst, index2, null); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitRegOffRegOperands(index2, scale2, disp2, dst); @@ -1337,6 +1387,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emitCMOV_Cond_Reg_Abs(byte cond, GPR dst, Address disp2) { int miStart = mi; + generateREXprefix(false, dst, null, null); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitAbsRegOperands(disp2, dst); @@ -1352,6 +1403,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3,4}) public final void emitCMOV_Cond_Reg_RegIdx(byte cond, GPR dst, GPR base2, GPR index2, short scale2, Offset disp2) { int miStart = mi; + generateREXprefix(false, dst, index2, base2); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x40, cond); emitSIBRegOperands(base2, index2, scale2, disp2, dst); @@ -1371,6 +1423,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emitSET_Cond_Reg_Byte(byte cond, GPR dst) { int miStart = mi; + generateREXprefix(false, null, null, dst); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitRegRegOperands(dst, EAX /* UNUSED */); @@ -1380,6 +1433,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emitSET_Cond_RegDisp_Byte(byte cond, GPR dst, Offset disp) { int miStart = mi; + generateREXprefix(false, null, null, dst); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitRegDispRegOperands(dst, disp, EAX /* UNUSED */); @@ -1389,6 +1443,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emitSET_Cond_RegInd_Byte(byte cond, GPR dst) { int miStart = mi; + generateREXprefix(false, null, null, dst); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitRegIndirectRegOperands(dst, EAX /* UNUSED */); @@ -1398,6 +1453,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2,3}) public final void emitSET_Cond_RegIdx_Byte(byte cond, GPR base, GPR index, short scale, Offset disp) { int miStart = mi; + generateREXprefix(false, null, index, base); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitSIBRegOperands(base, index, scale, disp, EAX /* UNUSED */); @@ -1407,6 +1463,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) public final void emitSET_Cond_RegOff_Byte(byte cond, GPR index, short scale, Offset disp) { int miStart = mi; + generateREXprefix(false, null, index, null); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitRegOffRegOperands(index, scale, disp, EAX /* UNUSED */); @@ -1416,6 +1473,7 @@ @Inline public final void emitSET_Cond_Abs_Byte(byte cond, Address disp) { int miStart = mi; + generateREXprefix(false, null, null, null); setMachineCodes(mi++, (byte) 0x0F); emitCondOpByte((byte)0x90, cond); emitAbsRegOperands(disp, EAX /* UNUSED */); @@ -1425,6 +1483,7 @@ @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) public final void emitIMUL2_Reg_Reg(GPR dstReg, GPR srcReg) { int miStart = mi; + generateREXprefix(false, dstReg, null, srcReg); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); emitRegRegOperands(srcReg, dstReg); @@ -1432,53 +1491,59 @@ } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitIMUL2_Reg_RegInd(GPR dstReg, GPR srcReg) { + public final void emitIMUL2_Reg_RegInd(GPR dstReg, GPR srcBase) { int miStart = mi; + generateREXprefix(false, dstReg, null, srcBase); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); - emitRegIndirectRegOperands(srcReg, dstReg); - if (lister != null) lister.RRN(miStart, "IMUL", dstReg, srcReg); + emitRegIndirectRegOperands(srcBase, dstReg); + if (lister != null) lister.RRN(miStart, "IMUL", dstReg, srcBase); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitIMUL2_Reg_RegDisp(GPR dstReg, GPR srcReg, Offset srcDisp) { + public final void emitIMUL2_Reg_RegDisp(GPR dstReg, GPR srcBase, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, null, srcBase); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); - emitRegDispRegOperands(srcReg, srcDisp, dstReg); - if (lister != null) lister.RRD(miStart, "IMUL", dstReg, srcReg, srcDisp); + emitRegDispRegOperands(srcBase, srcDisp, dstReg); + if (lister != null) lister.RRD(miStart, "IMUL", dstReg, srcBase, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitIMUL2_Reg_RegOff(GPR dstReg, GPR srcIndex, short scale, Offset disp) { + public final void emitIMUL2_Reg_RegOff(GPR dstReg, GPR srcIndex, short srcScale, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, srcIndex, null); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); - emitRegOffRegOperands(srcIndex, scale, disp, dstReg); - if (lister != null) lister.RRFD(miStart, "IMUL", dstReg, srcIndex, scale, disp); + emitRegOffRegOperands(srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRFD(miStart, "IMUL", dstReg, srcIndex, srcScale, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) - public final void emitIMUL2_Reg_Abs(GPR dstReg, Address disp) { + public final void emitIMUL2_Reg_Abs(GPR dstReg, Address srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, null, null); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); - emitAbsRegOperands(disp, dstReg); - if (lister != null) lister.RRA(miStart, "IMUL", dstReg, disp); + emitAbsRegOperands(srcDisp, dstReg); + if (lister != null) lister.RRA(miStart, "IMUL", dstReg, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitIMUL2_Reg_RegIdx(GPR dstReg, GPR srcBase, GPR srcIndex, short scale, Offset disp) { + public final void emitIMUL2_Reg_RegIdx(GPR dstReg, GPR srcBase, GPR srcIndex, short srcScale, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, srcIndex, srcBase); setMachineCodes(mi++, (byte) 0x0F); setMachineCodes(mi++, (byte) 0xAF); - emitSIBRegOperands(srcBase, srcIndex, scale, disp, dstReg); - if (lister != null) lister.RRXD(miStart, "IMUL", dstReg, srcBase, srcIndex, scale, disp); + emitSIBRegOperands(srcBase, srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRXD(miStart, "IMUL", dstReg, srcBase, srcIndex, srcScale, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) public final void emitIMUL2_Reg_Imm(GPR dstReg, int imm) { int miStart = mi; + generateREXprefix(false, dstReg, null, null); if (fits(imm,8)) { setMachineCodes(mi++, (byte) 0x6B); emitRegRegOperands(dstReg, dstReg); @@ -1491,6 +1556,82 @@ if (lister != null) lister.RI(miStart, "IMUL", dstReg, imm); } + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitIMUL2_Reg_Reg_Quad(GPR dstReg, GPR srcReg) { + int miStart = mi; + generateREXprefix(true, dstReg, null, srcReg); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitRegRegOperands(srcReg, dstReg); + if (lister != null) lister.RR(miStart, "IMUL", dstReg, srcReg); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitIMUL2_Reg_RegInd_Quad(GPR dstReg, GPR srcBase) { + int miStart = mi; + generateREXprefix(true, dstReg, null, srcBase); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitRegIndirectRegOperands(srcBase, dstReg); + if (lister != null) lister.RRN(miStart, "IMUL", dstReg, srcBase); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitIMUL2_Reg_RegDisp_Quad(GPR dstReg, GPR srcBase, Offset srcDisp) { + int miStart = mi; + generateREXprefix(true, dstReg, null, srcBase); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitRegDispRegOperands(srcBase, srcDisp, dstReg); + if (lister != null) lister.RRD(miStart, "IMUL", dstReg, srcBase, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitIMUL2_Reg_RegOff_Quad(GPR dstReg, GPR srcIndex, short srcScale, Offset srcDisp) { + int miStart = mi; + generateREXprefix(true, dstReg, srcIndex, null); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitRegOffRegOperands(srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRFD(miStart, "IMUL", dstReg, srcIndex, srcScale, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + public final void emitIMUL2_Reg_Abs_Quad(GPR dstReg, Address srcDisp) { + int miStart = mi; + generateREXprefix(true, dstReg, null, null); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitAbsRegOperands(srcDisp, dstReg); + if (lister != null) lister.RRA(miStart, "IMUL", dstReg, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitIMUL2_Reg_RegIdx_Quad(GPR dstReg, GPR srcBase, GPR srcIndex, short srcScale, Offset srcDisp) { + int miStart = mi; + generateREXprefix(true, dstReg, srcIndex, srcBase); + setMachineCodes(mi++, (byte) 0x0F); + setMachineCodes(mi++, (byte) 0xAF); + emitSIBRegOperands(srcBase, srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRXD(miStart, "IMUL", dstReg, srcBase, srcIndex, srcScale, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + public final void emitIMUL2_Reg_Imm_Quad(GPR dstReg, int imm) { + int miStart = mi; + generateREXprefix(true, dstReg, null, null); + if (fits(imm,8)) { + setMachineCodes(mi++, (byte) 0x6B); + emitRegRegOperands(dstReg, dstReg); + emitImm8((byte)imm); + } else { + setMachineCodes(mi++, (byte) 0x69); + emitRegRegOperands(dstReg, dstReg); + emitImm32(imm); + } + if (lister != null) lister.RI(miStart, "IMUL", dstReg, imm); + } + // trap public final void emitINT_Imm (int v) { if (VM.VerifyAssertions) VM._assert(v <= 0xFF); @@ -1594,61 +1735,121 @@ } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitLEA_Reg_RegDisp(GPR dstReg, GPR srcReg, Offset srcDisp) { + public final void emitLEA_Reg_RegDisp(GPR dstReg, GPR srcBase, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, null, srcBase); setMachineCodes(mi++, (byte) 0x8D); - emitRegDispRegOperands(srcReg, srcDisp, dstReg); - if (lister != null) lister.RRD(miStart, "LEA", dstReg, srcReg, srcDisp); + emitRegDispRegOperands(srcBase, srcDisp, dstReg); + if (lister != null) lister.RRD(miStart, "LEA", dstReg, srcBase, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitLEA_Reg_RegInd(GPR dstReg, GPR srcReg) { + public final void emitLEA_Reg_RegInd(GPR dstReg, GPR srcBase) { int miStart = mi; + generateREXprefix(false, dstReg, null, srcBase); setMachineCodes(mi++, (byte) 0x8D); - emitRegIndirectRegOperands(srcReg, dstReg); - if (lister != null) lister.RRN(miStart, "LEA", dstReg, srcReg); + emitRegIndirectRegOperands(srcBase, dstReg); + if (lister != null) lister.RRN(miStart, "LEA", dstReg, srcBase); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitLEA_Reg_RegOff(GPR dstReg, GPR idx, short scale, Offset disp) { + public final void emitLEA_Reg_RegOff(GPR dstReg, GPR srcIndex, short srcScale, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, srcIndex, null); setMachineCodes(mi++, (byte) 0x8D); - emitRegOffRegOperands(idx, scale, disp, dstReg); - if (lister != null) lister.RRFD(miStart, "LEA", dstReg, idx, scale, disp); + emitRegOffRegOperands(srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRFD(miStart, "LEA", dstReg, srcIndex, srcScale, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitLEA_Reg_Abs(GPR dstReg, Address disp) { + public final void emitLEA_Reg_Abs(GPR dstReg, Address srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, null, null); setMachineCodes(mi++, (byte) 0x8D); - emitAbsRegOperands(disp, dstReg); - if (lister != null) lister.RRA(miStart, "LEA", dstReg, disp); + emitAbsRegOperands(srcDisp, dstReg); + if (lister != null) lister.RRA(miStart, "LEA", dstReg, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitLEA_Reg_RegIdx(GPR dstReg, GPR base, GPR idx, short scale, Offset disp) { + public final void emitLEA_Reg_RegIdx(GPR dstReg, GPR srcBase, GPR srcIndex, short srcScale, Offset srcDisp) { int miStart = mi; + generateREXprefix(false, dstReg, srcIndex, srcBase); setMachineCodes(mi++, (byte) 0x8D); - emitSIBRegOperands(base, idx, scale, disp, dstReg); - if (lister != null) lister.RRXD(miStart, "LEA", dstReg, base, idx, scale, disp); + emitSIBRegOperands(srcBase, srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRXD(miStart, "LEA", dstReg, srcBase, srcIndex, srcScale, srcDisp); } @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitMOV_Reg_Imm(GPR dst, int imm) { + public final void emitLEA_Reg_RegDisp_Quad(GPR dstReg, GPR srcBase, Offset srcDisp) { int miStart = mi; - setMachineCodes(mi++, (byte) (0xB8 | dst.value())); + generateREXprefix(true, dstReg, null, srcBase); + setMachineCodes(mi++, (byte) 0x8D); + emitRegDispRegOperands(srcBase, srcDisp, dstReg); + if (lister != null) lister.RRD(miStart, "LEA", dstReg, srcBase, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitLEA_Reg_RegInd_Quad(GPR dstReg, GPR srcBase) { + int miStart = mi; + generateREXprefix(true, dstReg, null, srcBase); + setMachineCodes(mi++, (byte) 0x8D); + emitRegIndirectRegOperands(srcBase, dstReg); + if (lister != null) lister.RRN(miStart, "LEA", dstReg, srcBase); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitLEA_Reg_RegOff_Quad(GPR dstReg, GPR srcIndex, short srcScale, Offset srcDisp) { + int miStart = mi; + generateREXprefix(true, dstReg, srcIndex, null); + setMachineCodes(mi++, (byte) 0x8D); + emitRegOffRegOperands(srcIndex, srcScale, srcDisp, dstReg); + if (lister != null) lister.RRFD(miStart, "LEA", dstReg, srcIndex, srcScale, srcDisp); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) + public final void emitLEA_Reg_Abs_Quad(GPR dstReg, Address srcDisp) { + int miStart = mi; + generateREXprefix(tru... [truncated message content] |
From: <cap...@us...> - 2008-10-03 14:26:27
|
Revision: 15046 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15046&view=rev Author: captain5050 Date: 2008-10-03 14:26:22 +0000 (Fri, 03 Oct 2008) Log Message: ----------- Fix poor size estimation for short branches with tableswitch changes introduced in r15045. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/GenerateAssembler.java Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-10-02 22:16:59 UTC (rev 15045) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/mir2mc/ia32/AssemblerBase.java 2008-10-03 14:26:22 UTC (rev 15046) @@ -809,7 +809,7 @@ return size; } case MIR_LOWTABLESWITCH_opcode: - return MIR_LowTableSwitch.getNumberOfTargets(inst)*4 + 13; + return MIR_LowTableSwitch.getNumberOfTargets(inst)*4 + 14; case IA32_OFFSET_opcode: return 4; case IA32_JCC_opcode: @@ -1038,7 +1038,16 @@ AssemblerOpt asm = new AssemblerOpt(count, shouldPrint, ir); for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) { - p.setmcOffset(-++count); + // Set the mc offset of all instructions to their negative position. + // A positive value in their position means they have been created + // by the assembler. + count++; + p.setmcOffset(-count); + if (p.operator() == Operators.MIR_LOWTABLESWITCH) { + // Table switch kludge, as these will occupy multiple slots in the + // generated assembler + count += MIR_LowTableSwitch.getNumberOfTargets(p); + } } for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) { Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/GenerateAssembler.java =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/GenerateAssembler.java 2008-10-02 22:16:59 UTC (rev 15045) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler-opt/GenerateAssembler.java 2008-10-03 14:26:22 UTC (rev 15046) @@ -1248,8 +1248,10 @@ emitTab(1); emit("public void doInst(Instruction inst) {\n"); emitTab(2); - emit("resolveForwardReferences(++instructionCount);\n"); + emit("instructionCount++;\n"); emitTab(2); + emit("resolveForwardReferences(instructionCount);\n"); + emitTab(2); emit("switch (inst.getOpcode()) {\n"); Set<String> emittedOpcodes = new HashSet<String>(); @@ -1313,6 +1315,10 @@ emitTab(4); emit("doLOWTABLESWITCH(inst);\n"); emitTab(4); + emit("// kludge table switches that are unusually long instructions\n"); + emitTab(4); + emit("instructionCount += MIR_LowTableSwitch.getNumberOfTargets(inst);\n"); + emitTab(4); emit("break;\n"); Set<String> errorOpcodes = getErrorOpcodes(emittedOpcodes); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-11 21:12:01
|
Revision: 15097 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15097&view=rev Author: captain5050 Date: 2008-10-11 21:11:53 +0000 (Sat, 11 Oct 2008) Log Message: ----------- RVM-169 WIP: various 64bit fixes including syscall stack alignment. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-11 10:07:00 UTC (rev 15096) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-11 21:11:53 UTC (rev 15097) @@ -154,50 +154,46 @@ * (ie can we use a destructive short push/pop opcode) */ private void adjustStack(int size, boolean mayClobber) { + final boolean debug=false; if (size != 0) { if (mayClobber) { - if (VM.BuildFor32Addr) { - switch(size) { - case -8: + // first try short opcodes + switch(size >> LG_WORDSIZE) { + case -2: + if (debug) { + asm.emitPUSH_Imm(0xFA1FACE); + asm.emitPUSH_Imm(0xFA2FACE); + } else { asm.emitPUSH_Reg(EAX); asm.emitPUSH_Reg(EAX); - return; - case -4: - asm.emitPUSH_Reg(EAX); - return; - case 4: - asm.emitPOP_Reg(S0); - return; - case 8: - asm.emitPOP_Reg(S0); - asm.emitPOP_Reg(S0); - return; } - } else { - switch(size) { - case -16: - asm.emitPUSH_Reg(EAX); - asm.emitPUSH_Reg(EAX); - return; - case -8: - asm.emitPUSH_Reg(EAX); - return; - case 8: - asm.emitPOP_Reg(S0); - return; - case 16: - asm.emitPOP_Reg(S0); - asm.emitPOP_Reg(S0); - return; + return; + case -1: + if (debug) { + asm.emitPUSH_Imm(0xFA3FACE); + } else { + asm.emitPUSH_Reg(EAX); } + return; + case 1: + asm.emitPOP_Reg(S0); + if (debug) { + asm.emitMOV_Reg_Imm(S0, 0xFA4FACE); + } + return; + case 2: + asm.emitPOP_Reg(S0); + asm.emitPOP_Reg(S0); + if (debug) { + asm.emitMOV_Reg_Imm(S0, 0xFA5FACE); + } + return; } } if (VM.BuildFor32Addr) { - if (VM.BuildFor32Addr) { - asm.emitADD_Reg_Imm(SP, size); - } else { - asm.emitADD_Reg_Imm_Quad(SP, size); - } + asm.emitADD_Reg_Imm(SP, size); + } else { + asm.emitADD_Reg_Imm_Quad(SP, size); } } } @@ -326,10 +322,8 @@ asm.emitPUSH_Imm(0x3ff00000); asm.emitPUSH_Imm(0x00000000); } else { - // TODO: cache this value - Offset offset = Statics.slotAsOffset(Statics.findOrCreateLongSizeLiteral(0x3ff0000000000000L)); adjustStack(-WORDSIZE, true); - asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset)); + asm.emitPUSH_Abs(Magic.getTocPointer().plus(Entrypoints.oneDoubleField.getOffset())); } } @@ -340,7 +334,12 @@ */ @Override protected final void emit_ldc(Offset offset, byte type) { - asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset)); + if (VM.BuildFor32Addr || (type == RVMClass.CP_CLASS) || (type == RVMClass.CP_STRING)) { + asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset)); + } else { + asm.emitMOV_Reg_Abs(T0, Magic.getTocPointer().plus(offset)); + asm.emitPUSH_Reg(T0); + } } /** @@ -356,7 +355,7 @@ asm.emitMOVQ_Reg_Abs(XMM0, Magic.getTocPointer().plus(offset)); // XMM0 is constant value asm.emitMOVQ_RegInd_Reg(SP, XMM0); // place value on stack } else { - asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset).plus(4)); // high 32 bits + asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset).plus(WORDSIZE)); // high 32 bits asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset)); // low 32 bits } } else { @@ -366,8 +365,8 @@ } /* - * loading local variables - */ + * loading local variables + */ /** * Emit code to load an int local variable @@ -389,13 +388,8 @@ */ @Override protected final void emit_fload(int index) { - // identical to iload - code replicated for BaseBase compiler performance - Offset offset = localOffset(index); - if (offset.EQ(Offset.zero())) { - asm.emitPUSH_RegInd(ESP); - } else { - asm.emitPUSH_RegDisp(ESP, offset); - } + // identical to iload + emit_iload(index); } /** @@ -404,13 +398,8 @@ */ @Override protected final void emit_aload(int index) { - // identical to iload - code replicated for BaseBase compiler performance - Offset offset = localOffset(index); - if (offset.EQ(Offset.zero())) { - asm.emitPUSH_RegInd(ESP); - } else { - asm.emitPUSH_RegDisp(ESP, offset); - } + // identical to iload + emit_iload(index); } /** @@ -422,7 +411,7 @@ Offset offset = localOffset(index); if (VM.BuildFor32Addr) { if (SSE2_BASE) { - asm.emitMOVQ_Reg_RegDisp(XMM0, SP, offset.minus(4)); // XMM0 is local value + asm.emitMOVQ_Reg_RegDisp(XMM0, SP, offset.minus(WORDSIZE)); // XMM0 is local value adjustStack(-2*WORDSIZE, true); // adjust stack asm.emitMOVQ_RegInd_Reg(SP, XMM0); // place value on stack } else { @@ -431,7 +420,7 @@ } } else { adjustStack(-WORDSIZE, true); - asm.emitPUSH_Abs(Magic.getTocPointer().plus(offset)); + asm.emitPUSH_RegDisp(ESP, offset); } } @@ -442,7 +431,7 @@ @Override protected final void emit_dload(int index) { // identical to lload - emit_lload(index); + emit_lload(index); } /* @@ -455,7 +444,7 @@ */ @Override protected final void emit_istore(int index) { - Offset offset = localOffset(index).minus(4); // pop computes EA after ESP has moved by 4! + Offset offset = localOffset(index).minus(WORDSIZE); // pop computes EA after ESP has moved by WORDSIZE! if (offset.EQ(Offset.zero())) { asm.emitPOP_RegInd(ESP); } else { @@ -469,13 +458,8 @@ */ @Override protected final void emit_fstore(int index) { - // identical to istore - code replicated for BaseBase compiler performance - Offset offset = localOffset(index).minus(4); // pop computes EA after ESP has moved by 4! - if (offset.EQ(Offset.zero())) { - asm.emitPOP_RegInd(ESP); - } else { - asm.emitPOP_RegDisp(ESP, offset); - } + // identical to istore + emit_istore(index); } /** @@ -484,13 +468,8 @@ */ @Override protected final void emit_astore(int index) { - // identical to istore - code replicated for BaseBase compiler performance - Offset offset = localOffset(index).minus(4); // pop computes EA after ESP has moved by 4! - if (offset.EQ(Offset.zero())) { - asm.emitPOP_RegInd(ESP); - } else { - asm.emitPOP_RegDisp(ESP, offset); - } + // identical to istore + emit_istore(index); } /** @@ -501,20 +480,20 @@ protected final void emit_lstore(int index) { if (VM.BuildFor32Addr) { if (SSE2_BASE) { - Offset offset = localOffset(index).minus(4); + Offset offset = localOffset(index).minus(WORDSIZE); asm.emitMOVQ_Reg_RegInd(XMM0, SP); // XMM0 is stack value asm.emitMOVQ_RegDisp_Reg(SP, offset, XMM0); // place value in local adjustStack(2*WORDSIZE, true); } else { // pop computes EA after ESP has moved by 4! - Offset offset = localOffset(index + 1).minus(4); + Offset offset = localOffset(index + 1).minus(WORDSIZE); asm.emitPOP_RegDisp(ESP, offset); // high part asm.emitPOP_RegDisp(ESP, offset); // low part (ESP has moved by 4!!) } } else { - Offset offset = localOffset(index).minus(4); + Offset offset = localOffset(index + 1).minus(WORDSIZE); asm.emitPOP_RegDisp(ESP, offset); - asm.emitPOP_Reg(T0); // throw away top word + adjustStack(WORDSIZE, true); // throw away top word } } @@ -529,8 +508,8 @@ } /* - * array loads - */ + * array loads + */ /** * Emit code to load from an int array @@ -549,12 +528,8 @@ */ @Override protected final void emit_faload() { - // identical to iaload - code replicated for BaseBase compiler performance - asm.emitPOP_Reg(T0); // T0 is array index - asm.emitPOP_Reg(S0); // S0 is array ref - genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array - // push [S0+T0<<2] - asm.emitPUSH_RegIdx(S0, T0, Assembler.WORD, NO_SLOT); + // identical to iaload + emit_iaload(); } /** @@ -562,7 +537,6 @@ */ @Override protected final void emit_aaload() { - // identical to iaload - code replicated for BaseBase compiler performance asm.emitPOP_Reg(T0); // T0 is array index asm.emitPOP_Reg(T1); // T1 is array ref genBoundsCheck(asm, T0, T1); // T0 is index, T1 is address of array @@ -572,7 +546,7 @@ asm.emitPUSH_Reg(T0); // T0 is array index Barriers.compileArrayLoadBarrier(asm, true); } else { - asm.emitPUSH_RegIdx(T1, T0, Assembler.WORD, NO_SLOT); // push [S0+T0<<2] + asm.emitPUSH_RegIdx(T1, T0, (short)LG_WORDSIZE, NO_SLOT); // push [S0+T0*WORDSIZE] } } @@ -662,8 +636,8 @@ } /* - * array stores - */ + * array stores + */ /** * Emit code to store to an int array @@ -683,13 +657,8 @@ */ @Override protected final void emit_fastore() { - // identical to iastore - code replicated for BaseBase compiler performance - Barriers.compileModifyCheck(asm, 8); - asm.emitPOP_Reg(T1); // T1 is the value - asm.emitPOP_Reg(T0); // T0 is array index - asm.emitPOP_Reg(S0); // S0 is array ref - genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array - asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1 + // identical to iastore + emit_iastore(); } @@ -722,7 +691,7 @@ if (VM.BuildFor32Addr) { asm.emitMOV_RegIdx_Reg(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1 } else { - asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.WORD, NO_SLOT, T1); // [S0 + T0<<2] <- T1 + asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.LONG, NO_SLOT, T1); // [S0 + T0<<3] <- T1 } } } @@ -746,14 +715,8 @@ */ @Override protected final void emit_sastore() { - // identical to castore - code replicated for BaseBase compiler performance - Barriers.compileModifyCheck(asm, 8); - asm.emitPOP_Reg(T1); // T1 is the value - asm.emitPOP_Reg(T0); // T0 is array index - asm.emitPOP_Reg(S0); // S0 is array ref - genBoundsCheck(asm, T0, S0); // T0 is index, S0 is address of array - // store halfword element into array i.e. [S0 +T0] <- T1 (halfword) - asm.emitMOV_RegIdx_Reg_Word(S0, T0, Assembler.SHORT, NO_SLOT, T1); + // identical to castore + emit_castore(); } /** @@ -1174,6 +1137,7 @@ protected final void emit_ldiv() { if (VM.BuildFor64Addr) { asm.emitPOP_Reg(ECX); // ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements + asm.emitPOP_Reg(EAX); // throw away slot asm.emitPOP_Reg(EAX); // EAX is dividend asm.emitCDO(); // sign extend EAX into EDX asm.emitIDIV_Reg_Reg_Quad(EAX, ECX); @@ -1221,6 +1185,7 @@ protected final void emit_lrem() { if (VM.BuildFor64Addr) { asm.emitPOP_Reg(ECX); // ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements + asm.emitPOP_Reg(EAX); // throw away slot asm.emitPOP_Reg(EAX); // EAX is dividend asm.emitCDO(); // sign extend EAX into EDX asm.emitIDIV_Reg_Reg_Quad(EAX, ECX); @@ -1834,21 +1799,20 @@ asm.emitMOVSS_Reg_Abs(XMM0, Magic.getTocPointer().plus(Entrypoints.maxlongFloatField.getOffset())); // Set up value in XMM1 asm.emitMOVSS_Reg_RegInd(XMM1, SP); - adjustStack(-WORDSIZE, true); // Grow the stack // if value > maxint or NaN goto fr1; FP0 = value asm.emitUCOMISS_Reg_Reg(XMM0, XMM1); ForwardReference fr1 = asm.forwardJcc(Assembler.LLE); asm.emitCVTTSS2SI_Reg_Reg_Quad(T0, XMM1); - asm.emitMOV_RegInd_Reg_Quad(SP, T0); ForwardReference fr2 = asm.forwardJMP(); fr1.resolve(asm); ForwardReference fr3 = asm.forwardJcc(Assembler.PE); // if value == NaN goto fr3 - asm.emitMOV_RegInd_Imm_Quad(SP, 0x7FFFFFFFFFFFFFFFL); + asm.emitMOV_Reg_Imm_Quad(T0, 0x7FFFFFFFFFFFFFFFL); ForwardReference fr4 = asm.forwardJMP(); fr3.resolve(asm); - asm.emitMOV_RegInd_Imm_Quad(SP, 0); + asm.emitXOR_Reg_Reg(T0, T0); fr2.resolve(asm); fr4.resolve(asm); + asm.emitPUSH_Reg(T0); } } @@ -1948,20 +1912,21 @@ asm.emitMOVLPD_Reg_Abs(XMM0, Magic.getTocPointer().plus(Entrypoints.maxlongFloatField.getOffset())); // Set up value in XMM1 asm.emitMOVLPD_Reg_RegInd(XMM1, SP); + adjustStack(WORDSIZE, true); // if value > maxint or NaN goto fr1; FP0 = value asm.emitUCOMISD_Reg_Reg(XMM0, XMM1); ForwardReference fr1 = asm.forwardJcc(Assembler.LLE); asm.emitCVTTSD2SIQ_Reg_Reg_Quad(T0, XMM1); - asm.emitMOV_RegInd_Reg_Quad(SP, T0); ForwardReference fr2 = asm.forwardJMP(); fr1.resolve(asm); ForwardReference fr3 = asm.forwardJcc(Assembler.PE); // if value == NaN goto fr3 - asm.emitMOV_RegInd_Imm_Quad(SP, 0x7FFFFFFFFFFFFFFFL); + asm.emitMOV_Reg_Imm_Quad(T0, 0x7FFFFFFFFFFFFFFFL); ForwardReference fr4 = asm.forwardJMP(); fr3.resolve(asm); - asm.emitMOV_RegInd_Imm_Quad(SP, 0); + asm.emitXOR_Reg_Reg(T0, T0); fr2.resolve(asm); fr4.resolve(asm); + asm.emitPUSH_Reg(T0); } } @@ -2621,14 +2586,21 @@ } if (fieldRef.getSize() <= BYTES_IN_INT) { // get static field - [SP--] = [T0<<0+JTOC] - asm.emitPUSH_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); + if (VM.BuildFor32Addr) { + asm.emitPUSH_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); + } else { + asm.emitMOV_Reg_RegOff(T0, T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); + asm.emitPUSH_Reg(T0); + } } else { // field is two words (double or long) if (VM.VerifyAssertions) VM._assert(fieldRef.getSize() == BYTES_IN_LONG); if (VM.BuildFor32Addr) { asm.emitPUSH_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset().plus(WORDSIZE)); // get high part asm.emitPUSH_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); // get low part } else { - adjustStack(-WORDSIZE, true); + if (fieldRef.getNumberOfStackSlots() != 1) { + adjustStack(-WORDSIZE, true); + } asm.emitPUSH_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); } } @@ -2647,14 +2619,21 @@ return; } if (fieldRef.getSize() <= BYTES_IN_INT) { // field is one word - asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset)); + if (VM.BuildFor32Addr) { + asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset)); + } else { + asm.emitMOV_Reg_Abs(T0, Magic.getTocPointer().plus(fieldOffset)); + asm.emitPUSH_Reg(T0); + } } else { // field is two words (double or long) if (VM.VerifyAssertions) VM._assert(fieldRef.getSize() == BYTES_IN_LONG); if (VM.BuildFor32Addr) { asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset).plus(WORDSIZE)); // get high part asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset)); // get low part } else { - adjustStack(-WORDSIZE, true); + if (fieldRef.getNumberOfStackSlots() != 1) { + adjustStack(-WORDSIZE, true); + } asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset)); } } @@ -2685,7 +2664,9 @@ asm.emitPOP_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset().plus(WORDSIZE)); // store high part } else { asm.emitPOP_RegOff(T0, Assembler.BYTE, Magic.getTocPointer().toWord().toOffset()); - adjustStack(WORDSIZE, true); + if (fieldRef.getNumberOfStackSlots() != 1) { + adjustStack(WORDSIZE, true); + } } } } @@ -2717,7 +2698,9 @@ asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset).plus(WORDSIZE)); // store high part } else { asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset)); - adjustStack(WORDSIZE, true); + if (fieldRef.getNumberOfStackSlots() != 1) { + adjustStack(WORDSIZE, true); + } } } } @@ -2783,7 +2766,9 @@ asm.emitFSTP_RegInd_Reg_Quad(SP, FP0); // place value on stack } } else { - adjustStack(-WORDSIZE, true); // add empty slot + if (!fieldType.isWordType()) { + adjustStack(-WORDSIZE, true); // add empty slot + } asm.emitPUSH_RegIdx(T1, T0, Assembler.BYTE, NO_SLOT); // place value on stack } } @@ -2851,7 +2836,9 @@ asm.emitFSTP_RegInd_Reg_Quad(SP, FP0); // replace reference with value on stack } } else { - adjustStack(-WORDSIZE, true); // add empty slot + if (!fieldType.isWordType()) { + adjustStack(-WORDSIZE, true); // add empty slot + } asm.emitPUSH_RegDisp(T0, fieldOffset); // place value on stack } } @@ -2992,8 +2979,8 @@ if (!field.getType().isWordType()) { adjustStack(WORDSIZE, true); // throw away slot } - asm.emitPOP_Reg(S0); // T0 is the object reference - asm.emitMOV_RegIdx_Reg_Quad(S0, T0, Assembler.BYTE, NO_SLOT, T1); // [S0+T0] <- T1 + asm.emitPOP_Reg(S0); // S0 is the object reference + asm.emitMOV_RegDisp_Reg_Quad(S0, fieldOffset, T1); // [S0+fieldOffset] <- T1 } } } @@ -3798,7 +3785,7 @@ if (SSE2_FULL) { // TODO: Store SSE2 Control word? adjustStack(-XMM_STATE_SIZE, true); // adjust stack to bottom of saved area - if (VM.VerifyAssertions) VM._assert(XMM_SAVE_OFFSET.toInt() == -20 - XMM_STATE_SIZE); + if (VM.VerifyAssertions) VM._assert(XMM_SAVE_OFFSET.toInt() == (-5*WORDSIZE) - XMM_STATE_SIZE); asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(24), XMM3); asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(16), XMM2); asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(8), XMM1); @@ -4002,6 +3989,7 @@ if (JavaHeaderConstants.ARRAY_LENGTH_BYTES == 4) { asm.emitCMP_RegDisp_Reg(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg); } else { + asm.emitMOV_Reg_Reg(indexReg, indexReg); // clear MSBs asm.emitCMP_RegDisp_Reg_Quad(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg); } // Jmp around trap if index is OK @@ -4154,7 +4142,7 @@ max--; } } else { - asm.emitMOV_Reg_RegDisp_Quad(T, SP, offset); + asm.emitMOV_Reg_RegDisp_Quad(T, SP, offset.minus(WORDSIZE)); T = T1; // at most 2 parameters can be passed in general purpose registers gpr++; max--; @@ -4183,7 +4171,7 @@ max--; } offset = offset.minus(2 * WORDSIZE); - } else if (t.isReferenceType()) { + } else if (t.isReferenceType() || t.isWordType()) { if (gpr < NUM_PARAMETER_GPRS) { if (WORDSIZE == 4) { asm.emitMOV_Reg_RegDisp(T, SP, offset); // lo register := hi mem (== hi order word) @@ -4327,15 +4315,15 @@ for (int i = fpr - 1; 0 <= i; i--) { // unload the floating point register stack (backwards) if (is32bit[i]) { if (SSE2_BASE) { - asm.emitMOVSS_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-4), XMM.lookup(i)); + asm.emitMOVSS_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-WORDSIZE), XMM.lookup(i)); } else { - asm.emitFSTP_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-4), FP0); + asm.emitFSTP_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-WORDSIZE), FP0); } } else { if (SSE2_BASE) { - asm.emitMOVSD_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-4), XMM.lookup(i)); + asm.emitMOVSD_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-WORDSIZE), XMM.lookup(i)); } else { - asm.emitFSTP_RegDisp_Reg_Quad(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-4), FP0); + asm.emitFSTP_RegDisp_Reg_Quad(SP, Offset.fromIntSignExtend(fprOffset[i]-dstOffset-WORDSIZE), FP0); } } } @@ -4443,7 +4431,9 @@ } else if (m.isSysCall()) { TypeReference[] args = m.getParameterTypes(); TypeReference rtype = m.getReturnType(); - Offset offsetToJavaArg = THREE_SLOTS; // the three regs saved in (2) + Offset offsetToLastArg = THREE_SLOTS; // the three regs saved in (1) + Offset offsetToFirstArg = offsetToLastArg.plus((m.getParameterWords()-1) << LG_WORDSIZE); + boolean[] inRegister = VM.BuildFor32Addr ? null : new boolean[args.length]; int paramBytes = 0; // (1) save three RVM nonvolatile/special registers @@ -4454,46 +4444,185 @@ asm.emitPUSH_Reg(ESI); asm.emitPUSH_Reg(EDI); - // (2) Push args to target function (reversed), except for the first argument - for (int i = args.length - 1; i >= 1; i--) { - TypeReference arg = args[i]; - if (arg.isLongType() || arg.isDoubleType()) { - asm.emitPUSH_RegDisp(SP, offsetToJavaArg.plus(WORDSIZE)); - asm.emitPUSH_RegDisp(SP, offsetToJavaArg.plus(WORDSIZE)); - offsetToJavaArg = offsetToJavaArg.plus(4*WORDSIZE); - paramBytes += 2*WORDSIZE; + // (2) Pass args in registers passing from left-to-right + // (NB avoid the first argument holding the target function address) + int gpRegistersInUse = 0; + int fpRegistersInUse = 0; + Offset offsetToJavaArg = offsetToFirstArg; + if (VM.BuildFor64Addr) { + for (int i=1; i < args.length; i++) { + TypeReference arg = args[i]; + if (arg.isFloatType()) { + if (fpRegistersInUse < SYSCALL_PARAM_FPRS.length) { + inRegister[i] = true; + offsetToJavaArg = offsetToJavaArg.minus(WORDSIZE); + asm.emitMOVSS_Reg_RegDisp(SYSCALL_PARAM_FPRS[fpRegistersInUse], SP, offsetToJavaArg); + fpRegistersInUse++; + } + } else if (arg.isDoubleType()) { + if (fpRegistersInUse < SYSCALL_PARAM_FPRS.length) { + inRegister[i] = true; + offsetToJavaArg = offsetToJavaArg.minus(2*WORDSIZE); + asm.emitMOVSD_Reg_RegDisp(SYSCALL_PARAM_FPRS[fpRegistersInUse], SP, offsetToJavaArg); + fpRegistersInUse++; + } + } else if (arg.isLongType()) { + if (gpRegistersInUse < SYSCALL_PARAM_GPRS.length) { + inRegister[i] = true; + offsetToJavaArg = offsetToJavaArg.minus(2*WORDSIZE); + asm.emitMOV_Reg_RegDisp_Quad(SYSCALL_PARAM_GPRS[gpRegistersInUse], SP, offsetToJavaArg); + gpRegistersInUse++; + } + } else if (arg.isWordType() || arg.isReferenceType()) { + if (gpRegistersInUse < SYSCALL_PARAM_GPRS.length) { + inRegister[i] = true; + offsetToJavaArg = offsetToJavaArg.minus(WORDSIZE); + asm.emitMOV_Reg_RegDisp_Quad(SYSCALL_PARAM_GPRS[gpRegistersInUse], SP, offsetToJavaArg); + gpRegistersInUse++; + } + } else { + if (gpRegistersInUse < SYSCALL_PARAM_GPRS.length) { + inRegister[i] = true; + offsetToJavaArg = offsetToJavaArg.minus(WORDSIZE); + asm.emitMOV_Reg_RegDisp(SYSCALL_PARAM_GPRS[gpRegistersInUse], SP, offsetToJavaArg); + gpRegistersInUse++; + } + } + } + } + + // (3) Stack alignment + ForwardReference dontRealignStack = null; + int argsToPush=0; + if (VM.BuildFor64Addr) { + for (int i = args.length - 1; i >= 1; i--) { + if (!inRegister[i]) { + TypeReference arg = args[i]; + if (arg.isLongType() || arg.isDoubleType()) { + argsToPush += 2; + } else { + argsToPush ++; + } + } + } + asm.emitTEST_Reg_Imm(SP, 0x8); + if ((argsToPush & 1) != 0) { + dontRealignStack = asm.forwardJcc(Assembler.NE); } else { - asm.emitPUSH_RegDisp(SP, offsetToJavaArg); - offsetToJavaArg = offsetToJavaArg.plus(2*WORDSIZE); - paramBytes += WORDSIZE; + dontRealignStack = asm.forwardJcc(Assembler.EQ); } } - // (3) invoke target function with address given by the first argument - asm.emitMOV_Reg_RegDisp(S0, SP, offsetToJavaArg); - asm.emitCALL_Reg(S0); + // Generate argument pushing and call code upto twice, once with realignment + ForwardReference afterCalls = null; + for (int j= VM.BuildFor32Addr ? 1 : 0; j < 2; j++) { + if (j == 0) { + adjustStack(-WORDSIZE, true); + offsetToFirstArg = offsetToFirstArg.plus(WORDSIZE); + offsetToLastArg = offsetToLastArg.plus(WORDSIZE); + } else { + if (dontRealignStack != null) dontRealignStack.resolve(asm); + } + // (4) Stack remaining args to target function from right-to-left + // (NB avoid the first argument holding the target function address) + offsetToJavaArg = offsetToLastArg; + for (int i = args.length - 1; i >= 1; i--) { + TypeReference arg = args[i]; + if (VM.BuildFor32Addr) { + if (arg.isLongType() || arg.isDoubleType()) { + asm.emitPUSH_RegDisp(SP, offsetToJavaArg.plus(WORDSIZE)); + asm.emitPUSH_RegDisp(SP, offsetToJavaArg.plus(WORDSIZE)); + offsetToJavaArg = offsetToJavaArg.plus(4*WORDSIZE); + offsetToFirstArg = offsetToFirstArg.plus(2*WORDSIZE); + offsetToLastArg = offsetToLastArg.plus(2*WORDSIZE); + paramBytes += 2*WORDSIZE; + } else { + asm.emitPUSH_RegDisp(SP, offsetToJavaArg); + offsetToJavaArg = offsetToJavaArg.plus(2*WORDSIZE); + offsetToFirstArg = offsetToFirstArg.plus(WORDSIZE); + offsetToLastArg = offsetToLastArg.plus(WORDSIZE); + paramBytes += WORDSIZE; + } + } else { + if (!inRegister[i]) { + if (arg.isLongType() || arg.isDoubleType()) { + adjustStack(-WORDSIZE, true); + asm.emitPUSH_RegDisp(SP, offsetToJavaArg.plus(WORDSIZE)); + offsetToJavaArg = offsetToJavaArg.plus(4*WORDSIZE); + offsetToFirstArg = offsetToFirstArg.plus(2*WORDSIZE); + offsetToLastArg = offsetToLastArg.plus(2*WORDSIZE); + paramBytes += 2*WORDSIZE; + } else { + asm.emitPUSH_RegDisp(SP, offsetToJavaArg); + offsetToJavaArg = offsetToJavaArg.plus(2*WORDSIZE); + offsetToFirstArg = offsetToFirstArg.plus(WORDSIZE); + offsetToLastArg = offsetToLastArg.plus(WORDSIZE); + paramBytes += WORDSIZE; + } + } else { + if (arg.isLongType() || arg.isDoubleType()) { + offsetToJavaArg = offsetToJavaArg.plus(2*WORDSIZE); + } else { + offsetToJavaArg = offsetToJavaArg.plus(WORDSIZE); + } + } + } + } + if (VM.VerifyAssertions) VM._assert(offsetToFirstArg.EQ(offsetToJavaArg)); - // (4) pop space for arguments - adjustStack(paramBytes, true); + // (5) invoke target function with address given by the first argument + if (VM.BuildFor32Addr) { + asm.emitMOV_Reg_RegDisp(S0, SP, offsetToFirstArg); + asm.emitCALL_Reg(S0); + } else { + asm.emitMOV_Reg_RegDisp_Quad(T0, SP, offsetToFirstArg); + asm.emitCALL_Reg(T0); + } - // (5) restore RVM registers + // (6) pop space for arguments + if (j == 0) { + offsetToFirstArg = offsetToFirstArg.minus(WORDSIZE); + offsetToLastArg = offsetToLastArg.minus(WORDSIZE); + adjustStack(paramBytes+WORDSIZE, true); + afterCalls = asm.forwardJMP(); + } else { + adjustStack(paramBytes, true); + } + } + + if (afterCalls != null) afterCalls.resolve(asm); + + // (7) restore RVM registers asm.emitPOP_Reg(EDI); asm.emitPOP_Reg(ESI); asm.emitPOP_Reg(EBX); - // (6) pop expression stack (including the first parameter) - adjustStack(paramBytes+WORDSIZE, true); + // (8) pop expression stack (including the first parameter) + adjustStack(m.getParameterWords() << LG_WORDSIZE, true); - // (7) push return value + // (9) push return value if (rtype.isLongType()) { - asm.emitPUSH_Reg(T1); - asm.emitPUSH_Reg(T0); + if (VM.BuildFor32Addr) { + asm.emitPUSH_Reg(T1); + asm.emitPUSH_Reg(T0); + } else { + adjustStack(-WORDSIZE, true); + asm.emitPUSH_Reg(T0); + } } else if (rtype.isDoubleType()) { adjustStack(-2*WORDSIZE, true); - asm.emitFSTP_RegInd_Reg_Quad(SP, FP0); + if (VM.BuildFor32Addr) { + asm.emitFSTP_RegInd_Reg_Quad(SP, FP0); + } else { + asm.emitMOVSD_RegInd_Reg(SP, XMM0); + } } else if (rtype.isFloatType()) { adjustStack(-WORDSIZE, true); - asm.emitFSTP_RegInd_Reg(SP, FP0); + if (VM.BuildFor32Addr) { + asm.emitFSTP_RegInd_Reg(SP, FP0); + } else { + asm.emitMOVSS_RegInd_Reg(SP, XMM0); + } } else if (!rtype.isVoidType()) { asm.emitPUSH_Reg(T0); } Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-10-11 10:07:00 UTC (rev 15096) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-10-11 21:11:53 UTC (rev 15097) @@ -1390,8 +1390,6 @@ elif [ x$size = xquad ]; then ext="_Quad" rex_w=true - imm_type=long - immWrite=emitImm64 fi cat >> $FILENAME <<EOF /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-13 23:07:01
|
Revision: 15104 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15104&view=rev Author: captain5050 Date: 2008-10-13 23:06:51 +0000 (Mon, 13 Oct 2008) Log Message: ----------- Peep-hole optimization, "test reg,reg" is a shorter instruction that "cmp reg, 0", catch missed case. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-13 13:21:53 UTC (rev 15103) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-13 23:06:51 UTC (rev 15104) @@ -2195,7 +2195,7 @@ @Override protected final void emit_iflt(int bTarget) { asm.emitPOP_Reg(T0); - asm.emitCMP_Reg_Imm(T0, 0); + asm.emitTEST_Reg_Reg(T0, T0); genCondBranch(Assembler.LT, bTarget); } @@ -2206,7 +2206,7 @@ @Override protected final void emit_ifge(int bTarget) { asm.emitPOP_Reg(T0); - asm.emitCMP_Reg_Imm(T0, 0); + asm.emitTEST_Reg_Reg(T0, T0); genCondBranch(Assembler.GE, bTarget); } @@ -2217,7 +2217,7 @@ @Override protected final void emit_ifgt(int bTarget) { asm.emitPOP_Reg(T0); - asm.emitCMP_Reg_Imm(T0, 0); + asm.emitTEST_Reg_Reg(T0, T0); genCondBranch(Assembler.GT, bTarget); } @@ -2228,7 +2228,7 @@ @Override protected final void emit_ifle(int bTarget) { asm.emitPOP_Reg(T0); - asm.emitCMP_Reg_Imm(T0, 0); + asm.emitTEST_Reg_Reg(T0, T0); genCondBranch(Assembler.LE, bTarget); } @@ -3970,7 +3970,7 @@ @Inline private void genExplicitNullCheck(Assembler asm, GPR objRefReg) { // compare to zero - asm.emitCMP_Reg_Imm(objRefReg, 0); + asm.emitTEST_Reg_Reg(objRefReg, objRefReg); // Jmp around trap if index is OK asm.emitBranchLikelyNextInstruction(); ForwardReference fr = asm.forwardJcc(Assembler.NE); Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-10-13 13:21:53 UTC (rev 15103) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-10-13 23:06:51 UTC (rev 15104) @@ -527,13 +527,13 @@ EMIT(MIR_Compare.mutate(P(p), IA32_CMP, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal2(P(p)))); r: BOOLEAN_CMP_INT(r,INT_CONSTANT) -VR(p) == 0 && EQ_NE(BooleanCmp.getCond(P(p)))?37:INFINITE +VR(p) == 0 ? 37:INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p),MIR_Test.create(IA32_TEST, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal1(P(p)).copy())));\\ BOOLEAN_CMP_INT(P(p), BooleanCmp.getResult(P(p)), BooleanCmp.getCond(P(p))); boolcmp: BOOLEAN_CMP_INT(r,INT_CONSTANT) -VR(p) == 0 && EQ_NE(BooleanCmp.getCond(P(p)))?11:INFINITE +VR(p) == 0 ? 11:INFINITE EMIT_INSTRUCTION pushCOND(BooleanCmp.getCond(P(p))); \\ EMIT(CPOS(P(p),MIR_Test.create(IA32_TEST, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal1(P(p)).copy()))); @@ -682,7 +682,7 @@ CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); r: CMP_CMOV(r, OTHER_OPERAND(INT_CONSTANT, any)) -VRL(p) == 0 && EQ_NE(CondMove.getCond(P(p)))?(11 + 30):INFINITE +VRL(p) == 0 ? (11 + 30):INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p), MIR_Test.create(IA32_TEST, CondMove.getVal1(P(p)), CondMove.getVal1(P(p)).copy()))); \\ CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)), \\ @@ -2395,7 +2395,7 @@ IFCMP(P(p), IfCmp.getGuardResult(P(p)), IfCmp.getVal1(P(p)), IfCmp.getVal2(P(p)), IfCmp.getCond(P(p))); stm: INT_IFCMP(r, INT_CONSTANT) -VR(p) == 0 && EQ_NE(IfCmp.getCond(P(p)))?24:INFINITE +VR(p) == 0 ? 24:INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p), Move.create(GUARD_MOVE, IfCmp.getGuardResult(P(p)), new TrueGuardOperand()))); \\ EMIT(CPOS(P(p), MIR_Test.create(IA32_TEST, IfCmp.getVal1(P(p)), IfCmp.getVal1(P(p)).copy()))); \\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-14 14:23:37
|
Revision: 15106 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15106&view=rev Author: captain5050 Date: 2008-10-14 14:23:23 +0000 (Tue, 14 Oct 2008) Log Message: ----------- Don't reduce cmp to test in the case of unsigned conditions. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-10-14 01:31:29 UTC (rev 15105) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-10-14 14:23:23 UTC (rev 15106) @@ -471,6 +471,22 @@ throw new OptimizingCompilerException("BURS_Helpers", "unexpected 387 constant " + val); } + /** Can the given condition for a compare be converted to a test? */ + protected final boolean CMP_TO_TEST(ConditionOperand op) { + switch(op.value) { + case ConditionOperand.EQUAL: + case ConditionOperand.NOT_EQUAL: + case ConditionOperand.LESS: + case ConditionOperand.GREATER_EQUAL: + case ConditionOperand.GREATER: + case ConditionOperand.LESS_EQUAL: + case ConditionOperand.SAME: + case ConditionOperand.NOT_SAME: + default: + return false; + } + } + protected final IA32ConditionOperand COND(ConditionOperand op) { return new IA32ConditionOperand(op); } Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-10-14 01:31:29 UTC (rev 15105) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-10-14 14:23:23 UTC (rev 15106) @@ -527,13 +527,13 @@ EMIT(MIR_Compare.mutate(P(p), IA32_CMP, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal2(P(p)))); r: BOOLEAN_CMP_INT(r,INT_CONSTANT) -VR(p) == 0 ? 37:INFINITE +VR(p) == 0 && CMP_TO_TEST(BooleanCmp.getCond(P(p))) ? 37:INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p),MIR_Test.create(IA32_TEST, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal1(P(p)).copy())));\\ BOOLEAN_CMP_INT(P(p), BooleanCmp.getResult(P(p)), BooleanCmp.getCond(P(p))); boolcmp: BOOLEAN_CMP_INT(r,INT_CONSTANT) -VR(p) == 0 ? 11:INFINITE +VR(p) == 0 && CMP_TO_TEST(BooleanCmp.getCond(P(p))) ? 11:INFINITE EMIT_INSTRUCTION pushCOND(BooleanCmp.getCond(P(p))); \\ EMIT(CPOS(P(p),MIR_Test.create(IA32_TEST, BooleanCmp.getVal1(P(p)), BooleanCmp.getVal1(P(p)).copy()))); @@ -682,7 +682,7 @@ CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); r: CMP_CMOV(r, OTHER_OPERAND(INT_CONSTANT, any)) -VRL(p) == 0 ? (11 + 30):INFINITE +VRL(p) == 0 && CMP_TO_TEST(CondMove.getCond(P(p))) ? (11 + 30):INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p), MIR_Test.create(IA32_TEST, CondMove.getVal1(P(p)), CondMove.getVal1(P(p)).copy()))); \\ CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)), \\ @@ -2395,7 +2395,7 @@ IFCMP(P(p), IfCmp.getGuardResult(P(p)), IfCmp.getVal1(P(p)), IfCmp.getVal2(P(p)), IfCmp.getCond(P(p))); stm: INT_IFCMP(r, INT_CONSTANT) -VR(p) == 0 ? 24:INFINITE +VR(p) == 0 && CMP_TO_TEST(IfCmp.getCond(P(p))) ? 24:INFINITE EMIT_INSTRUCTION EMIT(CPOS(P(p), Move.create(GUARD_MOVE, IfCmp.getGuardResult(P(p)), new TrueGuardOperand()))); \\ EMIT(CPOS(P(p), MIR_Test.create(IA32_TEST, IfCmp.getVal1(P(p)), IfCmp.getVal1(P(p)).copy()))); \\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-19 11:41:15
|
Revision: 15122 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15122&view=rev Author: captain5050 Date: 2008-10-19 11:41:05 +0000 (Sun, 19 Oct 2008) Log Message: ----------- RVM-169 WIP: support for 64bit cmpxchg (not 8B) Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/ia32/ProcessorLocalState.java rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh Modified: rvmroot/trunk/rvm/src/org/jikesrvm/ia32/ProcessorLocalState.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/ia32/ProcessorLocalState.java 2008-10-19 11:39:49 UTC (rev 15121) +++ rvmroot/trunk/rvm/src/org/jikesrvm/ia32/ProcessorLocalState.java 2008-10-19 11:41:05 UTC (rev 15122) @@ -130,7 +130,11 @@ */ public static void emitCompareAndExchangeField(Assembler asm, Offset offset, GPR srcReg) { asm.emitLockNextInstruction(); - asm.emitCMPXCHG_RegDisp_Reg(PROCESSOR_REGISTER, offset, srcReg); + if (VM.BuildFor32Addr) { + asm.emitCMPXCHG_RegDisp_Reg(PROCESSOR_REGISTER, offset, srcReg); + } else { + asm.emitCMPXCHG_RegDisp_Reg_Quad(PROCESSOR_REGISTER, offset, srcReg); + } } /** Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-10-19 11:39:49 UTC (rev 15121) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-10-19 11:41:05 UTC (rev 15122) @@ -39,6 +39,11 @@ ext=_Quad code=" (quad) " rex_w=true + elif [ x$sizeOrPrefix = x0x0Fquad ]; then + ext=_Quad + code=" (quad) " + rex_w=true + twobyteop="setMachineCodes(mi++, (byte) 0x0F);" elif [ x$sizeOrPrefix = x0x0F ]; then twobyteop="setMachineCodes(mi++, (byte) 0x0F);" elif [ x$sizeOrPrefix != x ]; then @@ -1771,6 +1776,7 @@ emitMoveSubWord MOVZX "zero extended" 0xB6 0xB7 quad emitBinaryReg CMPXCHG \<\-\> 0xB1 none 0x0F +emitBinaryReg CMPXCHG \<\-\> 0xB1 none 0x0Fquad emitShift () { acronym=$1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-10-19 20:45:12
|
Revision: 15123 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15123&view=rev Author: captain5050 Date: 2008-10-19 20:45:03 +0000 (Sun, 19 Oct 2008) Log Message: ----------- Switch to using shorts for baseline locations, don't allocate location arrays on IA32, documentation improvements. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineGCMapIterator.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineGCMapIterator.java rvmroot/trunk/rvm/src/org/jikesrvm/osr/ppc/BaselineExecutionStateExtractor.java rvmroot/trunk/rvm/src-generated/vm-configuration/ArchitectureSpecific.template Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -42,6 +42,7 @@ /** Does the baseline compiled method have a counters array? */ private boolean hasCounters; + /** * The lock acquistion offset for synchronized methods. For * synchronized methods, the offset (in the method prologue) after @@ -63,9 +64,10 @@ */ public ReferenceMaps referenceMaps; - /* - * Currently needed to support dynamic bridge magic; - * Consider integrating with GC maps + /** + * Encoded representation of bytecode index to offset in code array + * map. Currently needed to support dynamic bridge magic; Consider + * integrating with GC maps */ private byte[] bytecodeMap; @@ -74,73 +76,92 @@ */ private int[] eTable; - /* To make a compiled method's stack offset independ of - * original method, we move 'getEmptyStackOffset' - * here. - * - * TODO: redesign this. There has to be a cleaner way! + /** Offset into stack frame when operand stack is empty */ + private final short emptyStackOffset; + /** PPC only: last general purpose register holding part of the operand stack */ + private byte lastFixedStackRegister; + /** PPC only: last floating point register holding part of the operand stack */ + private byte lastFloatStackRegister; + + /** + * PPC only: location of general purpose local variables, positive + * values are register numbers, negative are stack offsets */ - //private int startLocalOffset; - private final int emptyStackOffset; - private int lastFixedStackRegister; - private int lastFloatStackRegister; + private final short[] localFixedLocations; - private final int[] localFixedLocations; - private final int[] localFloatLocations; + /** + * PPC only: location of floating point local variables, positive + * values are register numbers, negative are stack offsets + */ + private final short[] localFloatLocations; -// public int getStartLocalOffset() { -// return startLocalOffset; -// } - + /** @return offset into stack frame when operand stack is empty */ public int getEmptyStackOffset() { return emptyStackOffset; } - //These Locations are positioned at the top of the stackslot that contains the value - //before accessing, substract size of value you want to access - //e.g. to load int: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_INT - //e.g. to load double: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_DOUBLE + /** + * Location of local general purpose variable. These Locations are + * positioned at the top of the stackslot that contains the value + * before accessing, substract size of value you want to access. + * e.g. to load int: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_INT + * e.g. to load long: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_LONG + */ @Uninterruptible - public int getGeneralLocalLocation(int localIndex) { + public short getGeneralLocalLocation(int localIndex) { return BaselineCompilerImpl.getGeneralLocalLocation(localIndex, localFixedLocations, (NormalMethod) method); } + /** + * Location of local floating point variable. These Locations are + * positioned at the top of the stackslot that contains the value + * before accessing, substract size of value you want to access. + * e.g. to load float: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_FLOAT + * e.g. to load double: load at BaselineCompilerImpl.locationToOffset(location) - BYTES_IN_DOUBLE + */ @Uninterruptible - public int getFloatLocalLocation(int localIndex) { + public short getFloatLocalLocation(int localIndex) { return BaselineCompilerImpl.getFloatLocalLocation(localIndex, localFloatLocations, (NormalMethod) method); } + /** Offset onto stack of a particular general purpose operand stack location */ @Uninterruptible - public int getGeneralStackLocation(int stackIndex) { + public short getGeneralStackLocation(int stackIndex) { return BaselineCompilerImpl.offsetToLocation(emptyStackOffset - (stackIndex << LOG_BYTES_IN_ADDRESS)); } + /** Offset onto stack of a particular operand stack location for a floating point value */ @Uninterruptible - public int getFloatStackLocation(int stackIndex) { //for now same implementation as getGeneralStackLocation, todo - return BaselineCompilerImpl.offsetToLocation(emptyStackOffset - (stackIndex << LOG_BYTES_IN_ADDRESS)); + public short getFloatStackLocation(int stackIndex) { + // for now same implementation as getGeneralStackLocation + return getGeneralStackLocation(stackIndex); } + /** Last general purpose register holding part of the operand stack */ @Uninterruptible public int getLastFixedStackRegister() { return lastFixedStackRegister; } + /** Last floating point register holding part of the operand stack */ @Uninterruptible public int getLastFloatStackRegister() { return lastFloatStackRegister; } + /** Constructor */ public BaselineCompiledMethod(int id, RVMMethod m) { super(id, m); NormalMethod nm = (NormalMethod) m; //this.startLocalOffset = BaselineCompilerImpl.getStartLocalOffset(nm); - this.emptyStackOffset = BaselineCompilerImpl.getEmptyStackOffset(nm); - this.localFixedLocations = new int[nm.getLocalWords()]; - this.localFloatLocations = new int[nm.getLocalWords()]; + this.emptyStackOffset = (short)BaselineCompilerImpl.getEmptyStackOffset(nm); + this.localFixedLocations = VM.BuildForIA32 ? null : new short[nm.getLocalWords()]; + this.localFloatLocations = VM.BuildForIA32 ? null : new short[nm.getLocalWords()]; this.lastFixedStackRegister = -1; this.lastFloatStackRegister = -1; } + /** Compile method */ public void compile() { BaselineCompilerImpl comp = new BaselineCompilerImpl(this, localFixedLocations, localFloatLocations); comp.compile(); @@ -148,20 +169,31 @@ this.lastFloatStackRegister = comp.getLastFloatStackRegister(); } + /** @return BASELINE */ @Uninterruptible public int getCompilerType() { return BASELINE; } + /** @return "baseline compiler" */ public String getCompilerName() { return "baseline compiler"; } + /** + * Get the exception deliverer for this kind of compiled method + */ @Uninterruptible public ExceptionDeliverer getExceptionDeliverer() { return exceptionDeliverer; } + /** + * Find a catch block within the compiled method + * @param instructionOffset offset of faulting instruction in compiled code + * @param exceptionType the type of the thrown exception + * @return the machine code offset of the catch block. + */ @Unpreemptible public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { if (eTable == null) { @@ -171,6 +203,31 @@ } } + /** + * Fetch symbolic reference to a method that's called by one of + * this method's instructions. + * @param dynamicLink place to put return information + * @param instructionOffset offset of machine instruction from start of + * this method, in bytes + * + * Notes: + * <ul> + * <li> The "instructionOffset" must point to the instruction i + * <em> following </em> the call + * instruction whose target method is sought. + * This allows us to properly handle the case where + * the only address we have to work with is a return address + * (ie. from a stackframe) + * on a machine architecture with variable length instructions. + * In such situations we'd have no idea how far to back up the + * instruction pointer + * to point to the "call site". + * + * <li> The implementation must not cause any allocations, + * because it executes with + * gc disabled when called by GCMapIterator. + * <ul> + */ @Uninterruptible public void getDynamicLink(DynamicLink dynamicLink, Offset instructionOffset) { int bytecodeIndex = findBytecodeIndexForInstruction(instructionOffset); @@ -201,15 +258,15 @@ * Find bytecode index corresponding to one of this method's * machine instructions. * - * Note: This method expects the instructionIndex to refer to the machine - * instruction immediately FOLLOWING the bytecode in question. - * just like findLineNumberForInstruction. See CompiledMethod - * for rationale - * NOTE: instructionIndex is in units of instructions, not bytes (different from - * all the other methods in this interface!!) - * - * @return the bytecode index for the machine instruction, -1 if - * not available or not found. + * @param instructionOffset instruction offset to map to a bytecode index + * Note: This method expects the offset to refer to the machine + * instruction immediately FOLLOWING the bytecode in question. just + * like findLineNumberForInstruction. See CompiledMethod for + * rationale + * NOTE: instructionIndex is in units of instructions, not bytes + * (different from all the other methods in this interface!!) + * @return the bytecode index for the machine instruction, -1 if not + * available or not found. */ @Uninterruptible public int findBytecodeIndexForInstruction(Offset instructionOffset) { @@ -264,9 +321,11 @@ return false; } - // Print this compiled method's portion of a stack trace - // Taken: offset of machine instruction from start of method - // the PrintLN to print the stack trace to. + /** + * Print this compiled method's portion of a stack trace + * @param offset of machine instruction from start of method + * @param the PrintLN to print the stack trace to. + */ public void printStackTrace(Offset instructionOffset, PrintLN out) { out.print("\tat "); out.print(method.getDeclaringClass()); // RVMClass @@ -316,11 +375,13 @@ return hasCounters; } - // Taken: method that was compiled - // bytecode-index to machine-instruction-index map for method - // number of instructions for method - // - public void encodeMappingInfo(ReferenceMaps referenceMaps, int[] bcMap, int numInstructions) { + /** + * Encode/compress the bytecode map, reference (GC) map and exception table + * + * @param referenceMaps to encode + * @param bcMap unencoded bytecode to code array offset map + */ + public void encodeMappingInfo(ReferenceMaps referenceMaps, int[] bcMap) { int count = 0; int lastBC = 0, lastIns = 0; for (int i = 0; i < bcMap.length; i++) { @@ -364,6 +425,7 @@ lastIns = bcMap[i]; } } + // TODO: it's likely for short methods we can share the bytecodeMap referenceMaps.translateByte2Machine(bcMap); this.referenceMaps = referenceMaps; ExceptionHandlerMap emap = ((NormalMethod) method).getExceptionHandlerMap(); @@ -372,9 +434,13 @@ } } - private static final TypeReference TYPE = TypeReference.findOrCreate(BaselineCompiledMethod.class); - + /** + * Return the number of bytes used to encode the compiler-specific mapping + * information for this compiled method. + * Used to gather stats on the space costs of mapping schemes. + */ public int size() { + TypeReference TYPE = TypeReference.findOrCreate(BaselineCompiledMethod.class); int size = TYPE.peekType().asClass().getInstanceSize(); if (bytecodeMap != null) size += RVMArray.ByteArray.getInstanceSize(bytecodeMap.length); if (eTable != null) size += RVMArray.IntArray.getInstanceSize(eTable.length); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiler.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -295,7 +295,7 @@ if (method.isSynchronized()) { ((BaselineCompiledMethod) compiledMethod).setLockAcquisitionOffset(lockOffset); } - ((BaselineCompiledMethod) compiledMethod).encodeMappingInfo(refMaps, bcMap, instructions.length()); + ((BaselineCompiledMethod) compiledMethod).encodeMappingInfo(refMaps, bcMap); compiledMethod.compileComplete(instructions); if (edgeCounterIdx > 0) { EdgeCounts.allocateCounters(method, edgeCounterIdx); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -89,34 +89,34 @@ //nothing to do for intel } - public final int getLastFixedStackRegister() { + public final byte getLastFixedStackRegister() { return -1; //doesn't dedicate registers to stack; } - public final int getLastFloatStackRegister() { + public final byte getLastFloatStackRegister() { return -1; //doesn't dedicate registers to stack; } @Uninterruptible - public static int getGeneralLocalLocation(int index, int[] localloc, NormalMethod m) { + public static short getGeneralLocalLocation(int index, short[] localloc, NormalMethod m) { return offsetToLocation(getStartLocalOffset(m) - (index << LOG_BYTES_IN_ADDRESS)); //we currently do not use location arrays on intel } @Uninterruptible - public static int getFloatLocalLocation(int index, int[] localloc, NormalMethod m) { + public static short getFloatLocalLocation(int index, short[] localloc, NormalMethod m) { return offsetToLocation(getStartLocalOffset(m) - (index << LOG_BYTES_IN_ADDRESS)); //we currently do not use location arrays on intel } @Uninterruptible - public static int locationToOffset(int location) { + public static int locationToOffset(short location) { return -location; } @Uninterruptible - public static int offsetToLocation(int offset) { - return -offset; + public static short offsetToLocation(int offset) { + return (short)-offset; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineGCMapIterator.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineGCMapIterator.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineGCMapIterator.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -174,7 +174,7 @@ * given a index in the local area (biased : local0 has index 1) * this routine determines the correspondig offset in the stack */ - public int convertIndexToLocation(int index) { + public short convertIndexToLocation(int index) { if (index == 0) return 0; if (index <= currentNumLocals) { //index is biased by 1; return currentCompiledMethod.getGeneralLocalLocation(index - 1); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineCompilerImpl.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -66,31 +66,34 @@ private final int startLocalOffset; private int spillOffset; - // current offset of the sp from fp + /** Current offset of the sp from fp, also accessed by Assembler */ public int spTopOffset; - // If we're doing a short forward jump of less than - // this number of bytecodes, then we can always use a short-form - // conditional branch (don't have to emit a nop & bc). + /** + * If we're doing a short forward jump of less than this number of + * bytecodes, then we can always use a short-form conditional branch + * (don't have to emit a nop & bc). + */ private static final int SHORT_FORWARD_LIMIT = 500; private static final boolean USE_NONVOLATILE_REGISTERS = true; - private int firstFixedStackRegister; //after the fixed local registers !! - private int firstFloatStackRegister; //after the float local registers !! + private byte firstFixedStackRegister; //after the fixed local registers !! + private byte firstFloatStackRegister; //after the float local registers !! - private int lastFixedStackRegister; - private int lastFloatStackRegister; + private byte lastFixedStackRegister; + private byte lastFloatStackRegister; - private final int[] localFixedLocations; - private final int[] localFloatLocations; + private final short[] localFixedLocations; + private final short[] localFloatLocations; + /** Can non-volatile registers be used? */ private final boolean use_nonvolatile_registers; /** * Create a Compiler object for the compilation of method. */ - protected BaselineCompilerImpl(BaselineCompiledMethod cm, int[] genLocLoc, int[] floatLocLoc) { + protected BaselineCompilerImpl(BaselineCompiledMethod cm, short[] genLocLoc, short[] floatLocLoc) { super(cm); localFixedLocations = genLocLoc; localFloatLocations = floatLocLoc; @@ -115,8 +118,7 @@ // more interface // //----------------// - // position of operand stack within method's stackframe. - + /** position of operand stack within method's stackframe */ @Uninterruptible public static int getEmptyStackOffset(NormalMethod m) { int params = m.getOperandWords() << LOG_BYTES_IN_STACKSLOT; // maximum parameter area @@ -126,14 +128,14 @@ return STACKFRAME_HEADER_SIZE + spill + stack; } - // start position of locals within method's stackframe. + /** start position of locals within method's stackframe */ @Uninterruptible private static int getInternalStartLocalOffset(NormalMethod m) { int locals = m.getLocalWords() << LOG_BYTES_IN_STACKSLOT; // input param words + pure locals return getEmptyStackOffset(m) + locals; // bottom-most local } - // size of method's stackframe. + /** size of method's stackframe. */ @Uninterruptible private int getInternalFrameSize() { int size = startLocalOffset; @@ -150,8 +152,7 @@ return size; } - // size of method's stackframe. - // only valid on compiled methods + /** size of method's stackframe. NB only valid on compiled methods */ @Uninterruptible public static int getFrameSize(BaselineCompiledMethod bcm) { NormalMethod m = (NormalMethod) bcm.getMethod(); @@ -173,15 +174,15 @@ private void defineStackAndLocalLocations() { - int nextFixedLocalRegister = FIRST_FIXED_LOCAL_REGISTER; - int nextFloatLocalRegister = FIRST_FLOAT_LOCAL_REGISTER; + short nextFixedLocalRegister = FIRST_FIXED_LOCAL_REGISTER; + short nextFloatLocalRegister = FIRST_FLOAT_LOCAL_REGISTER; //define local registers int nparam = method.getParameterWords(); TypeReference[] types = method.getParameterTypes(); int localIndex = 0; if (!method.isStatic()) { - if (localTypes[0] != ADDRESS_TYPE) VM._assert(false); + if (VM.VerifyAssertions) VM._assert(localTypes[0] == ADDRESS_TYPE); if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER)) { localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex)); } else { @@ -277,13 +278,13 @@ //else unused, assign nothing, can be the case after long or double } - firstFixedStackRegister = nextFixedLocalRegister; - firstFloatStackRegister = nextFloatLocalRegister; + firstFixedStackRegister = (byte)nextFixedLocalRegister; + firstFloatStackRegister = (byte)nextFloatLocalRegister; //define stack registers //KV: TODO - lastFixedStackRegister = firstFixedStackRegister - 1; - lastFloatStackRegister = firstFloatStackRegister - 1; + lastFixedStackRegister = (byte)(firstFixedStackRegister - 1); + lastFloatStackRegister = (byte)(firstFloatStackRegister - 1); if (USE_NONVOLATILE_REGISTERS && method.hasBaselineSaveLSRegistersAnnotation()) { //methods with SaveLSRegisters pragma need to save/restore ALL registers in their prolog/epilog @@ -292,11 +293,11 @@ } } - public final int getLastFixedStackRegister() { + public final byte getLastFixedStackRegister() { return lastFixedStackRegister; } - public final int getLastFloatStackRegister() { + public final byte getLastFloatStackRegister() { return lastFloatStackRegister; } @@ -312,43 +313,43 @@ return 0 != (type & (LONG_TYPE)); } - private int getGeneralLocalLocation(int index) { + private short getGeneralLocalLocation(int index) { return localFixedLocations[index]; } - private int getFloatLocalLocation(int index) { + private short getFloatLocalLocation(int index) { return localFloatLocations[index]; } @Uninterruptible @Inline - public static int getGeneralLocalLocation(int index, int[] localloc, NormalMethod m) { + public static short getGeneralLocalLocation(int index, short[] localloc, NormalMethod m) { return localloc[index]; } @Uninterruptible @Inline - public static int getFloatLocalLocation(int index, int[] localloc, NormalMethod m) { + public static short getFloatLocalLocation(int index, short[] localloc, NormalMethod m) { return localloc[index]; } /* - * implementation of abstract methods of BaselineCompiler - */ + * implementation of abstract methods of BaselineCompiler + */ /* * Misc routines not directly tied to a particular bytecode */ - private int getSingleStackLocation(int index) { + private short getSingleStackLocation(int index) { return offsetToLocation(spTopOffset + BYTES_IN_STACKSLOT + (index << LOG_BYTES_IN_STACKSLOT)); } - private int getDoubleStackLocation(int index) { + private short getDoubleStackLocation(int index) { return offsetToLocation(spTopOffset + 2 * BYTES_IN_STACKSLOT + (index << LOG_BYTES_IN_STACKSLOT)); } - private int getTopOfStackLocationForPush() { + private short getTopOfStackLocationForPush() { return offsetToLocation(spTopOffset); } @@ -768,7 +769,7 @@ */ @Override protected final void emit_iload(int index) { - int dstLoc = getTopOfStackLocationForPush(); + short dstLoc = getTopOfStackLocationForPush(); copyByLocation(INT_TYPE, getGeneralLocalLocation(index), INT_TYPE, dstLoc); spTopOffset -= BYTES_IN_STACKSLOT; } @@ -779,7 +780,7 @@ */ @Override protected final void emit_lload(int index) { - int dstLoc = getTopOfStackLocationForPush(); + short dstLoc = getTopOfStackLocationForPush(); copyByLocation(LONG_TYPE, getGeneralLocalLocation(index), LONG_TYPE, dstLoc); spTopOffset -= 2 * BYTES_IN_STACKSLOT; } @@ -790,7 +791,7 @@ */ @Override protected final void emit_fload(int index) { - int dstLoc = getTopOfStackLocationForPush(); + short dstLoc = getTopOfStackLocationForPush(); copyByLocation(FLOAT_TYPE, getFloatLocalLocation(index), FLOAT_TYPE, dstLoc); spTopOffset -= BYTES_IN_STACKSLOT; } @@ -801,7 +802,7 @@ */ @Override protected final void emit_dload(int index) { - int dstLoc = getTopOfStackLocationForPush(); + short dstLoc = getTopOfStackLocationForPush(); copyByLocation(DOUBLE_TYPE, getFloatLocalLocation(index), DOUBLE_TYPE, dstLoc); spTopOffset -= 2 * BYTES_IN_STACKSLOT; } @@ -812,14 +813,14 @@ */ @Override protected final void emit_aload(int index) { - int dstLoc = getTopOfStackLocationForPush(); + short dstLoc = getTopOfStackLocationForPush(); copyByLocation(ADDRESS_TYPE, getGeneralLocalLocation(index), ADDRESS_TYPE, dstLoc); spTopOffset -= BYTES_IN_STACKSLOT; } /* - * storing local variables - */ + * storing local variables + */ /** * Emit code to store an int to a local variable @@ -827,7 +828,7 @@ */ @Override protected final void emit_istore(int index) { - int srcLoc = getSingleStackLocation(0); + short srcLoc = getSingleStackLocation(0); copyByLocation(INT_TYPE, srcLoc, INT_TYPE, getGeneralLocalLocation(index)); discardSlot(); } @@ -848,7 +849,7 @@ */ @Override protected final void emit_fstore(int index) { - int srcLoc = getSingleStackLocation(0); + short srcLoc = getSingleStackLocation(0); copyByLocation(FLOAT_TYPE, srcLoc, FLOAT_TYPE, getFloatLocalLocation(index)); discardSlot(); } @@ -859,7 +860,7 @@ */ @Override protected final void emit_dstore(int index) { - int srcLoc = getDoubleStackLocation(0); + short srcLoc = getDoubleStackLocation(0); copyByLocation(DOUBLE_TYPE, srcLoc, DOUBLE_TYPE, getFloatLocalLocation(index)); discardSlots(2); } @@ -870,7 +871,7 @@ */ @Override protected final void emit_astore(int index) { - int srcLoc = getSingleStackLocation(0); + short srcLoc = getSingleStackLocation(0); copyByLocation(ADDRESS_TYPE, srcLoc, ADDRESS_TYPE, getGeneralLocalLocation(index)); discardSlot(); } @@ -975,8 +976,8 @@ } /* - * array stores - */ + * array stores + */ /** * Emit code to store to an int array @@ -1332,13 +1333,13 @@ */ @Override protected final void emit_iinc(int index, int val) { - int loc = getGeneralLocalLocation(index); + short loc = getGeneralLocalLocation(index); if (isRegister(loc)) { asm.emitADDI(loc, val, loc); } else { - copyMemToReg(INT_TYPE, locationToOffset(loc), T0); + copyMemToReg(INT_TYPE, locationToOffset(loc), (short)T0); asm.emitADDI(T0, val, T0); - copyRegToMem(INT_TYPE, T0, locationToOffset(loc)); + copyRegToMem(INT_TYPE, (short)T0, locationToOffset(loc)); } } @@ -2253,10 +2254,10 @@ * @param index local variable containing the return address */ protected final void emit_ret(int index) { - int location = getGeneralLocalLocation(index); + short location = getGeneralLocalLocation(index); if (!isRegister(location)) { - copyMemToReg(ADDRESS_TYPE, locationToOffset(location), T0); + copyMemToReg(ADDRESS_TYPE, locationToOffset(location), (short)T0); location = T0; } asm.emitMTLR(location); @@ -3361,22 +3362,22 @@ } @Uninterruptible - public static boolean isRegister(int location) { + public static boolean isRegister(short location) { return location > 0; } @Uninterruptible - public static int locationToOffset(int location) { + public static int locationToOffset(short location) { return -location; } @Uninterruptible - public static int offsetToLocation(int offset) { - return -offset; + public static short offsetToLocation(int offset) { + return (short)-offset; } @Inline - private void copyRegToReg(byte srcType, int src, int dest) { + private void copyRegToReg(byte srcType, short src, short dest) { if ((srcType == FLOAT_TYPE) || (srcType == DOUBLE_TYPE)) { asm.emitFMR(dest, src); } else { @@ -3388,7 +3389,7 @@ } @Inline - private void copyRegToMem(byte srcType, int src, int dest) { + private void copyRegToMem(byte srcType, short src, int dest) { if (srcType == FLOAT_TYPE) { asm.emitSTFS(src, dest - BYTES_IN_FLOAT, FP); } else if (srcType == DOUBLE_TYPE) { @@ -3404,7 +3405,7 @@ } @Inline - private void copyMemToReg(byte srcType, int src, int dest) { + private void copyMemToReg(byte srcType, int src, short dest) { if (srcType == FLOAT_TYPE) { asm.emitLFS(dest, src - BYTES_IN_FLOAT, FP); } else if (srcType == DOUBLE_TYPE) { @@ -3461,17 +3462,14 @@ * @param dest the destination location */ @Inline - private void copyByLocation(byte srcType, int src, byte destType, int dest) { + private void copyByLocation(byte srcType, short src, byte destType, short dest) { if (src == dest && srcType == destType) { return; } - boolean srcIsRegister = isRegister(src); - boolean destIsRegister = isRegister(dest); + final boolean srcIsRegister = isRegister(src); + final boolean destIsRegister = isRegister(dest); - if (!srcIsRegister) src = locationToOffset(src); - if (!destIsRegister) dest = locationToOffset(dest); - if (srcType == destType) { if (srcIsRegister) { if (destIsRegister) { @@ -3479,37 +3477,37 @@ copyRegToReg(srcType, src, dest); } else { // register to memory move - copyRegToMem(srcType, src, dest); + copyRegToMem(srcType, src, locationToOffset(dest)); } } else { if (destIsRegister) { // memory to register move - copyMemToReg(srcType, src, dest); + copyMemToReg(srcType, locationToOffset(src), dest); } else { // memory to memory move - copyMemToMem(srcType, src, dest); + copyMemToMem(srcType, locationToOffset(src), locationToOffset(dest)); } } } else {// no matching types if ((srcType == DOUBLE_TYPE) && (destType == LONG_TYPE) && srcIsRegister && !destIsRegister) { - asm.emitSTFD(src, dest - BYTES_IN_DOUBLE, FP); + asm.emitSTFD(src, locationToOffset(dest) - BYTES_IN_DOUBLE, FP); } else if ((srcType == LONG_TYPE) && (destType == DOUBLE_TYPE) && destIsRegister && !srcIsRegister) { - asm.emitLFD(dest, src - BYTES_IN_LONG, FP); + asm.emitLFD(dest, locationToOffset(src) - BYTES_IN_LONG, FP); } else if ((srcType == INT_TYPE) && (destType == LONGHALF_TYPE) && srcIsRegister && VM.BuildFor32Addr) { //Used as Hack if 1 half of long is spilled if (destIsRegister) { asm.emitMR(dest, src); } else { - asm.emitSTW(src, dest - BYTES_IN_LONG, FP); // lo mem := lo register (== hi word) + asm.emitSTW(src, locationToOffset(dest) - BYTES_IN_LONG, FP); // lo mem := lo register (== hi word) } } else if ((srcType == LONGHALF_TYPE) && (destType == INT_TYPE) && !srcIsRegister && VM.BuildFor32Addr) { //Used as Hack if 1 half of long is spilled if (destIsRegister) { - asm.emitLWZ(dest + 1, src - BYTES_IN_INT, FP); + asm.emitLWZ(dest + 1, locationToOffset(src) - BYTES_IN_INT, FP); } else { - asm.emitLWZ(0, src - BYTES_IN_INT, FP); - asm.emitSTW(0, dest - BYTES_IN_INT, FP); + asm.emitLWZ(0, locationToOffset(src) - BYTES_IN_INT, FP); + asm.emitSTW(0, locationToOffset(dest) - BYTES_IN_INT, FP); } } else // implement me @@ -3664,7 +3662,7 @@ Offset klassOffset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass.getClassForType())); asm.emitLAddrToc(T0, klassOffset); } else { // first local is "this" pointer - copyByLocation(ADDRESS_TYPE, getGeneralLocalLocation(0), ADDRESS_TYPE, T0); + copyByLocation(ADDRESS_TYPE, getGeneralLocalLocation(0), ADDRESS_TYPE, (short)T0); } asm.emitLAddrOffset(S0, JTOC, Entrypoints.lockMethod.getOffset()); // call out... asm.emitMTCTR(S0); // ...of line lock @@ -3679,7 +3677,7 @@ Offset klassOffset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass.getClassForType())); asm.emitLAddrToc(T0, klassOffset); } else { // first local is "this" pointer - copyByLocation(ADDRESS_TYPE, getGeneralLocalLocation(0), ADDRESS_TYPE, T0); + copyByLocation(ADDRESS_TYPE, getGeneralLocalLocation(0), ADDRESS_TYPE, (short)T0); } asm.emitLAddrOffset(S0, JTOC, Entrypoints.unlockMethod.getOffset()); // call out... asm.emitMTCTR(S0); // ...of line lock @@ -3845,12 +3843,12 @@ private void genMoveParametersToLocals() { // AIX computation will differ int spillOff = frameSize + STACKFRAME_HEADER_SIZE; - int gp = FIRST_VOLATILE_GPR; - int fp = FIRST_VOLATILE_FPR; + short gp = FIRST_VOLATILE_GPR; + short fp = FIRST_VOLATILE_FPR; int localIndex = 0; - int srcLocation; - int dstLocation; + short srcLocation; + short dstLocation; byte type; if (!method.isStatic()) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineExceptionDeliverer.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -81,7 +81,7 @@ lock = method.getDeclaringClass().getResolvedClassForType(); } else { Address fp = registers.getInnermostFramePointer(); - int location = bcm.getGeneralLocalLocation(0); + short location = bcm.getGeneralLocalLocation(0); Address addr; if (BaselineCompilerImpl.isRegister(location)) { lock = Magic.addressAsObject(registers.gprs.get(location).toAddress()); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineGCMapIterator.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineGCMapIterator.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineGCMapIterator.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -105,7 +105,7 @@ int JSRindex = maps.setupJSRSubroutineMap(mapId); while (JSRindex != 0) { Address nextCallerAddress; - int location = convertIndexToLocation(JSRindex); + short location = convertIndexToLocation(JSRindex); if (BaselineCompilerImpl.isRegister(location)) { nextCallerAddress = registerLocations.get(location).toAddress(); } else { @@ -190,21 +190,22 @@ * given a index in the local area (biased : local0 has index 1) * this routine determines the correspondig offset in the stack */ - public int convertIndexToLocation(int index) { + public short convertIndexToLocation(int index) { if (index == 0) return 0; if (index <= currentNumLocals) { //index is biased by 1; - return currentCompiledMethod.getGeneralLocalLocation(index - - 1); //register (positive value) or stacklocation (negative value) + //register (positive value) or stacklocation (negative value) + return currentCompiledMethod.getGeneralLocalLocation(index - 1); } else { + //locations must point to the top of the slot return currentCompiledMethod.getGeneralStackLocation(index - 1 - currentNumLocals); - //(BaselineCompilerImpl.offsetToLocation(maps.convertIndexToOffset(index) + BYTES_IN_STACKSLOT)); //locations must point to the top of the slot } } - // Get location of next reference. - // A zero return indicates that no more references exist. - // + /** + * Get location of next reference. + * A zero return indicates that no more references exist. + */ public Address getNextReferenceAddress() { if (!finishedWithRegularMap) { @@ -224,7 +225,7 @@ } if (mapIndex != 0) { - int location = convertIndexToLocation(mapIndex); + short location = convertIndexToLocation(mapIndex); if (VM.TraceStkMaps) { VM.sysWrite("BaselineGCMapIterator getNextReference location = "); VM.sysWrite(location); @@ -366,7 +367,7 @@ if (mapIndex == 0) return Address.zero(); - int location = convertIndexToLocation(mapIndex); + short location = convertIndexToLocation(mapIndex); if (VM.TraceStkMaps) { VM.sysWrite("BaselineGCMapIterator getNextReturnAddress location = "); VM.sysWrite(location); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/osr/ppc/BaselineExecutionStateExtractor.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/osr/ppc/BaselineExecutionStateExtractor.java 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src/org/jikesrvm/osr/ppc/BaselineExecutionStateExtractor.java 2008-10-19 20:45:03 UTC (rev 15123) @@ -220,7 +220,7 @@ int size = localTypes.length; for (int i = 0; i < size; i++) { if ((localTypes[i] == ClassTypeCode) || (localTypes[i] == ArrayTypeCode)) { - int loc = fooCM.getGeneralLocalLocation(i); + short loc = fooCM.getGeneralLocalLocation(i); if (BaselineCompilerImpl.isRegister(loc)) { objs[loc] = Magic.addressAsObject(gprs.get(loc).toAddress()); } @@ -267,7 +267,7 @@ case ShortTypeCode: case CharTypeCode: case IntTypeCode: { - int loc = compiledMethod.getGeneralLocalLocation(i); + short loc = compiledMethod.getGeneralLocalLocation(i); int value; if (BaselineCompilerImpl.isRegister(loc)) { value = registers.gprs.get(loc).toInt(); @@ -279,7 +279,7 @@ break; } case LongTypeCode: { - int loc = compiledMethod.getGeneralLocalLocation(i); + short loc = compiledMethod.getGeneralLocalLocation(i); long lvalue; if (BaselineCompilerImpl.isRegister(loc)) { if (VM.BuildFor32Addr) { @@ -301,7 +301,7 @@ break; } case FloatTypeCode: { - int loc = compiledMethod.getFloatLocalLocation(i); + short loc = compiledMethod.getFloatLocalLocation(i); int value; if (BaselineCompilerImpl.isRegister(loc)) { value = Magic.floatAsIntBits((float) registers.fprs[loc]); @@ -313,7 +313,7 @@ break; } case DoubleTypeCode: { - int loc = compiledMethod.getFloatLocalLocation(i); + short loc = compiledMethod.getFloatLocalLocation(i); long lvalue; if (BaselineCompilerImpl.isRegister(loc)) { lvalue = Magic.doubleAsLongBits(registers.fprs[loc]); @@ -330,7 +330,7 @@ break; } case ReturnAddressTypeCode: { - int loc = compiledMethod.getGeneralLocalLocation(i); + short loc = compiledMethod.getGeneralLocalLocation(i); VM.disableGC(); Address rowIP; if (BaselineCompilerImpl.isRegister(loc)) { @@ -360,7 +360,7 @@ case ClassTypeCode: case ArrayTypeCode: { - int loc = compiledMethod.getGeneralLocalLocation(i); + short loc = compiledMethod.getGeneralLocalLocation(i); Object ref; if (BaselineCompilerImpl.isRegister(loc)) { ref = registers.objs[loc]; @@ -373,7 +373,7 @@ break; } case WordTypeCode: { - int loc = compiledMethod.getGeneralLocalLocation(i); + short loc = compiledMethod.getGeneralLocalLocation(i); Word value; if (BaselineCompilerImpl.isRegister(loc)) { value = registers.gprs.get(loc); Modified: rvmroot/trunk/rvm/src-generated/vm-configuration/ArchitectureSpecific.template =================================================================== --- rvmroot/trunk/rvm/src-generated/vm-configuration/ArchitectureSpecific.template 2008-10-19 11:41:05 UTC (rev 15122) +++ rvmroot/trunk/rvm/src-generated/vm-configuration/ArchitectureSpecific.template 2008-10-19 20:45:03 UTC (rev 15123) @@ -45,7 +45,7 @@ } } public static final class BaselineCompilerImpl extends org.jikesrvm.compilers.baseline.@_ARCH_@.BaselineCompilerImpl { - public BaselineCompilerImpl(BaselineCompiledMethod cm, int[] genLocLoc, int[] floatLocLoc) { + public BaselineCompilerImpl(BaselineCompiledMethod cm, short[] genLocLoc, short[] floatLocLoc) { super(cm @_IA32_QUOTE_@, genLocLoc, floatLocLoc @_PPC_QUOTE_@ */); }} public static final class DynamicLinkerHelper extends org.jikesrvm.@_ARCH_@.DynamicLinkerHelper {} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-05 00:05:26
|
Revision: 15222 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15222&view=rev Author: captain5050 Date: 2008-12-05 00:05:23 +0000 (Fri, 05 Dec 2008) Log Message: ----------- Improve javadoc of options, use a common empty iterator utility class to avoid having multiple anonymous classes. Modified Paths: -------------- rvmroot/trunk/rvm/src-generated/options/MasterOptions.template rvmroot/trunk/rvm/src-generated/options/OptOptions.template Added Paths: ----------- rvmroot/trunk/rvm/src/org/jikesrvm/util/EmptyIterator.java Added: rvmroot/trunk/rvm/src/org/jikesrvm/util/EmptyIterator.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/util/EmptyIterator.java (rev 0) +++ rvmroot/trunk/rvm/src/org/jikesrvm/util/EmptyIterator.java 2008-12-05 00:05:23 UTC (rev 15222) @@ -0,0 +1,28 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.jikesrvm.util; + +import java.util.Iterator; + +/** + * A generic iterator containing no items + */ +public final class EmptyIterator<T> implements Iterator<T> { + public boolean hasNext() { + return false; + } + public T next() { + return null; + } + public void remove() {} +} Modified: rvmroot/trunk/rvm/src-generated/options/MasterOptions.template =================================================================== --- rvmroot/trunk/rvm/src-generated/options/MasterOptions.template 2008-12-05 00:03:55 UTC (rev 15221) +++ rvmroot/trunk/rvm/src-generated/options/MasterOptions.template 2008-12-05 00:05:23 UTC (rev 15222) @@ -15,7 +15,8 @@ $$$$ FOREACH OPTION BDATFILE $$$$ SPLIT "OPTION.DECL" " " FULL_NAME OPT_LEVEL DEFAULT_VALUE SHORT_NAME $$$$ LET PRETTY_NAME @PAD(FULL_NAME,30," ") - public boolean PRETTY_NAME= DEFAULT_VALUE; // OPTION.DESCRIP + /** OPTION.DESCRIP */ + public boolean PRETTY_NAME= DEFAULT_VALUE; $$$$ END LET PRETTY_NAME $$$$ END SPLIT $$$$ END FOREACH @@ -25,11 +26,13 @@ $$$$ SPLIT "OPTION.DECL" " " TAG FULL_NAME TYPE DEFAULT_VALUE SHORT_NAME $$$$ IF TAG == S $$$$ LET PRETTY_NAME @PAD(FULL_NAME,23-@LENGTH("TYPE")," ") - private java.util.HashSet<String> PRETTY_NAME= null; // OPTION.DESCRIP + /** OPTION.DESCRIP */ + private java.util.HashSet<TYPE> PRETTY_NAME= null; $$$$ END LET PRETTY_NAME $$$$ ELSE $$$$ LET PRETTY_NAME @PAD(FULL_NAME,37-@LENGTH("TYPE")," ") - public TYPE PRETTY_NAME= DEFAULT_VALUE; // OPTION.DESCRIP + /** OPTION.DESCRIP */ + public TYPE PRETTY_NAME= DEFAULT_VALUE; $$$$ END LET PRETTY_NAME $$$$ END IF $$$$ END SPLIT @@ -46,7 +49,12 @@ $$$$ LOOP CONSTNAME OPTION.ENUMS $$$$ SPLIT "CONSTNAME" " " ITEM_NAME QUERRY_NAME CMD_NAME public static final TYPE ITEM_NAME = CONSTNAME.INDEX; - public final boolean QUERRY_NAME() { return FULL_NAME == ITEM_NAME; } + /** + * Is FULL_NAME set to ITEM_NAME? + */ + public final boolean QUERRY_NAME() { + return FULL_NAME == ITEM_NAME; + } $$$$ END SPLIT CONSTNAME $$$$ END LOOP @@ -62,22 +70,38 @@ $$$$ SPLIT "OPTION.DECL" " " TAG FULL_NAME TYPE DEFAULT_VALUE SHORT_NAME $$$$ IF TAG == S // FULL_NAME - public boolean isFULL_NAME(TYPE q) { return FULL_NAME != null && FULL_NAME.contains(q); } + /** + * Has the given parameter been added to FULL_NAME set of options? + */ + public boolean isFULL_NAME(TYPE q) { + return FULL_NAME != null && FULL_NAME.contains(q); + } + $$$$ IF TYPE == String + /** + * Does the given parameter appear within a set the String of one of the options? + */ public boolean fuzzyMatchFULL_NAME(TYPE q) { - if (FULL_NAME == null) return false; - for (final String s : FULL_NAME) { - if (q.indexOf(s) > -1) return true; + if (FULL_NAME != null) { + for (final String s : FULL_NAME) { + if (q.indexOf(s) > -1) + return true; + } } return false; } - public boolean hasFULL_NAME() { return !(FULL_NAME == null || FULL_NAME.isEmpty()); } - public java.util.Iterator<String> getFULL_NAMEs() { + $$$$ END IF TYPE == String + /** + * Have any items been placed in the set FULL_NAME? + */ + public boolean hasFULL_NAME() { + return FULL_NAME != null && !FULL_NAME.isEmpty(); + } + /** + * Return an iterator over the items in FULL_NAME + */ + public java.util.Iterator<TYPE> getFULL_NAMEs() { if (FULL_NAME == null) { - return new java.util.Iterator<String>() { - public boolean hasNext() { return false; } - public String next() { return null; } - public void remove() {} - }; + return new org.jikesrvm.util.EmptyIterator<TYPE>(); } else { return FULL_NAME.iterator(); } @@ -97,7 +121,7 @@ $$$$ SPLIT "OPTION.DECL" " " TAG FULL_NAME TYPE DEFAULT_VALUE SHORT_NAME $$$$ IF TAG == S if (FULL_NAME != null) { - clone.FULL_NAME = (java.util.HashSet)this.FULL_NAME.clone(); + clone.FULL_NAME = (java.util.HashSet<TYPE>)this.FULL_NAME.clone(); } $$$$ END IF $$$$ END SPLIT @@ -117,7 +141,6 @@ } } - /** * Take a string (most likely a command-line argument) and try to proccess it * as an option command. Return true if the string was understood, false @@ -174,7 +197,7 @@ FULL_NAME = true; return true; } else if (value.equals("false")) { - FULL_NAME = false; + FULL_NAME = false; return true; } else return false; @@ -199,10 +222,10 @@ FULL_NAME = (byte)CommandLineArgs.primitiveParseInt(value); $$$$ ELSE $$$$ IF TYPE == double - FULL_NAME = CommandLineArgs.primitiveParseFloat(value); + FULL_NAME = CommandLineArgs.primitiveParseFloat(value); $$$$ ELSE $$$$ IF TYPE == float - FULL_NAME = CommandLineArgs.primitiveParseFloat(value); + FULL_NAME = CommandLineArgs.primitiveParseFloat(value); $$$$ ELSE Hey! You tried to declare a value option of unrecoginized type...fix it! $$$$ END IF @@ -226,16 +249,12 @@ } $$$$ ELSE $$$$ IF TAG == S - $$$$ IF TYPE == String if (FULL_NAME == null) { - FULL_NAME = new java.util.HashSet<String>(); + FULL_NAME = new java.util.HashSet<TYPE>(); } FULL_NAME.add(value); return true; } - $$$$ ELSE - Hey! You tried to declare a Set option of unsupported type...fix it! - $$$$ END IF TYPE == String $$$$ ELSE Whoops! Unimplemented tag: TAG...go nag Dave and he'll finish it. $$$$ END IF TAG == S @@ -251,7 +270,7 @@ return false; } - // Print a short description of every option + /** Print a short description of every option */ public static void printHelp(String prefix) { instancePrintHelpHeader(prefix); @@ -325,7 +344,7 @@ VM.sysExit(VM.EXIT_STATUS_PRINTED_HELP_MESSAGE); } - // print the options values + /** @return a String representing the options values */ @org.vmmagic.pragma.NoOptCompile public String toString() { StringBuilder result = new StringBuilder(); @@ -384,7 +403,8 @@ return result.toString(); //End generated toString() } - // return a String value of this options object + + /** print a String value of this options object */ @org.vmmagic.pragma.NoOptCompile public void printOptions() { printOptionsHeader(); Modified: rvmroot/trunk/rvm/src-generated/options/OptOptions.template =================================================================== --- rvmroot/trunk/rvm/src-generated/options/OptOptions.template 2008-12-05 00:03:55 UTC (rev 15221) +++ rvmroot/trunk/rvm/src-generated/options/OptOptions.template 2008-12-05 00:05:23 UTC (rev 15222) @@ -71,13 +71,15 @@ } - // accessor to get OPT level + /** accessor to get OPT level */ public int getOptLevel() { return OPTIMIZATION_LEVEL; } - // Set the options to encode the optimizations enabled at the given opt label - // and disabled all optimizations that are not enabled at the given opt label + /** + * Set the options to encode the optimizations enabled at the given opt label + * and disabled all optimizations that are not enabled at the given opt label + */ public void setOptLevel(int level) { OPTIMIZATION_LEVEL = level; // Begin generated opt-level logic This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dgr...@us...> - 2008-12-06 02:33:53
|
Revision: 15223 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15223&view=rev Author: dgrove-oss Date: 2008-12-06 02:33:49 +0000 (Sat, 06 Dec 2008) Log Message: ----------- RVM-725 WIP : Delete a number of unsound experimental opt options. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/ppc/GenerateMachineSpecificMagic.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/YieldPoints.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ObjectReplacer.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/UnsyncReplacer.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -2265,16 +2265,14 @@ } RegisterOperand refinedOp2 = gc.temps.makeTemp(op2); - if (!gc.options.NO_CHECKCAST) { - if (classLoading) { - s = TypeCheck.create(CHECKCAST_UNRESOLVED, refinedOp2, op2.copy(), makeTypeOperand(typeRef)); + if (classLoading) { + s = TypeCheck.create(CHECKCAST_UNRESOLVED, refinedOp2, op2.copy(), makeTypeOperand(typeRef)); + } else { + TypeOperand typeOp = makeTypeOperand(typeRef.peekType()); + if (isNonNull(op2)) { + s = TypeCheck.create(CHECKCAST_NOTNULL, refinedOp2, op2.copy(), typeOp, getGuard(op2)); } else { - TypeOperand typeOp = makeTypeOperand(typeRef.peekType()); - if (isNonNull(op2)) { - s = TypeCheck.create(CHECKCAST_NOTNULL, refinedOp2, op2.copy(), typeOp, getGuard(op2)); - } else { - s = TypeCheck.create(CHECKCAST, refinedOp2, op2.copy(), typeOp); - } + s = TypeCheck.create(CHECKCAST, refinedOp2, op2.copy(), typeOp); } } refinedOp2.refine(typeRef); @@ -2336,11 +2334,7 @@ break; } if (VM.VerifyAssertions) VM._assert(op0.isRef()); - if (gc.options.MONITOR_NOP) { - s = null; - } else { - s = MonitorOp.create(MONITORENTER, op0, getCurrentGuard()); - } + s = MonitorOp.create(MONITORENTER, op0, getCurrentGuard()); } break; @@ -2350,11 +2344,7 @@ if (do_NullCheck(op0)) { break; } - if (gc.options.MONITOR_NOP) { - s = null; - } else { - s = MonitorOp.create(MONITOREXIT, op0, getCurrentGuard()); - } + s = MonitorOp.create(MONITOREXIT, op0, getCurrentGuard()); rectifyStateWithExceptionHandler(TypeReference.JavaLangIllegalMonitorStateException); } break; @@ -3821,9 +3811,6 @@ * @return true if an unconditional throw is generated, false otherwise */ private boolean do_CheckStore(Operand ref, Operand elem, TypeReference elemType) { - if (gc.options.NO_CHECKSTORE) { - return false; // Unsafely eliminate all store checks - } if (CF_CHECKSTORE) { // NOTE: BE WARY OF ADDITIONAL OPTIMZATIONS. // ARRAY SUBTYPING IS SUBTLE (see JLS 10.10) --dave Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -528,14 +528,14 @@ * Should null checks be generated? */ boolean noNullChecks() { - return options.NO_NULL_CHECK || method.hasNoNullCheckAnnotation(); + return method.hasNoNullCheckAnnotation(); } /** * Should bounds checks be generated? */ boolean noBoundsChecks() { - return options.NO_BOUNDS_CHECK || method.hasNoBoundsCheckAnnotation(); + return method.hasNoBoundsCheckAnnotation(); } /** @@ -666,7 +666,7 @@ // since it's the second time reenter if (method.isForOsrSpecialization()) { // do nothing - } else if (method.isSynchronized() && !options.MONITOR_NOP && !options.INVOKEE_THREAD_LOCAL) { + } else if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { Operand lockObject = getLockObject(); Instruction s = MonitorOp.create(MONITORENTER, lockObject, new TrueGuardOperand()); appendInstruction(prologue, s, SYNCHRONIZED_MONITORENTER_BCI); @@ -679,7 +679,7 @@ */ private void completeEpilogue(boolean isOutermost) { // Deal with implicit monitorexit for synchronized methods. - if (method.isSynchronized() && !options.MONITOR_NOP && !options.INVOKEE_THREAD_LOCAL) { + if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { Operand lockObject = getLockObject(); Instruction s = MonitorOp.create(MONITOREXIT, lockObject, new TrueGuardOperand()); appendInstruction(epilogue, s, SYNCHRONIZED_MONITOREXIT_BCI); @@ -705,7 +705,7 @@ * PRECONDITION: cfg, arguments & temps have been setup/initialized. */ private void completeExceptionHandlers(boolean isOutermost) { - if (method.isSynchronized() && !options.MONITOR_NOP) { + if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { ExceptionHandlerBasicBlock rethrow = new ExceptionHandlerBasicBlock(SYNTH_CATCH_BCI, inlineSequence, Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/ppc/GenerateMachineSpecificMagic.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/ppc/GenerateMachineSpecificMagic.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/ppc/GenerateMachineSpecificMagic.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -123,13 +123,9 @@ new IntConstantOperand(STACKFRAME_NEXT_INSTRUCTION_OFFSET))); bc2ir.push(val.copyD2U()); } else if (methodName == MagicNames.isync) { - if (!gc.options.NO_CACHE_FLUSH) { - bc2ir.appendInstruction(Empty.create(READ_CEILING)); - } + bc2ir.appendInstruction(Empty.create(READ_CEILING)); } else if (methodName == MagicNames.sync) { - if (!gc.options.NO_CACHE_FLUSH) { - bc2ir.appendInstruction(Empty.create(WRITE_FLOOR)); - } + bc2ir.appendInstruction(Empty.create(WRITE_FLOOR)); } else if (methodName == MagicNames.pause) { // IA-specific } else if (methodName == MagicNames.dcbst) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/YieldPoints.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/YieldPoints.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/YieldPoints.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -19,7 +19,6 @@ import static org.jikesrvm.compilers.opt.ir.Operators.YIELDPOINT_PROLOGUE; import org.jikesrvm.VM; -import org.jikesrvm.compilers.opt.OptOptions; import org.jikesrvm.compilers.opt.driver.CompilerPhase; import org.jikesrvm.compilers.opt.inlining.InlineSequence; import org.jikesrvm.compilers.opt.ir.BasicBlock; @@ -38,15 +37,6 @@ public class YieldPoints extends CompilerPhase { /** - * Should this phase be performed? - * @param options controlling compiler options - * @return true or false - */ - public final boolean shouldPerform(OptOptions options) { - return !options.NO_THREADS; - } - - /** * Return the name of this phase * @return "Yield Point Insertion" */ Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ObjectReplacer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ObjectReplacer.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ObjectReplacer.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -201,20 +201,12 @@ } break; case MONITORENTER_opcode: - if (ir.options.NO_CACHE_FLUSH) { - DefUse.removeInstructionAndUpdateDU(inst); - } else { - inst.insertBefore(Empty.create(READ_CEILING)); - DefUse.removeInstructionAndUpdateDU(inst); - } + inst.insertBefore(Empty.create(READ_CEILING)); + DefUse.removeInstructionAndUpdateDU(inst); break; case MONITOREXIT_opcode: - if (ir.options.NO_CACHE_FLUSH) { - DefUse.removeInstructionAndUpdateDU(inst); - } else { - inst.insertBefore(Empty.create(WRITE_FLOOR)); - DefUse.removeInstructionAndUpdateDU(inst); - } + inst.insertBefore(Empty.create(WRITE_FLOOR)); + DefUse.removeInstructionAndUpdateDU(inst); break; case CALL_opcode: case NULL_CHECK_opcode: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/UnsyncReplacer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/UnsyncReplacer.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/UnsyncReplacer.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -117,18 +117,14 @@ if (DEBUG) { VM.sysWrite("Removing " + inst); } - if (!options.NO_CACHE_FLUSH) { - inst.insertBefore(Empty.create(READ_CEILING)); - } + inst.insertBefore(Empty.create(READ_CEILING)); DefUse.removeInstructionAndUpdateDU(inst); break; case MONITOREXIT_opcode: if (DEBUG) { VM.sysWrite("Removing " + inst); } - if (!options.NO_CACHE_FLUSH) { - inst.insertAfter(Empty.create(WRITE_FLOOR)); - } + inst.insertAfter(Empty.create(WRITE_FLOOR)); DefUse.removeInstructionAndUpdateDU(inst); break; default: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-06 02:33:49 UTC (rev 15223) @@ -308,71 +308,63 @@ break; case MONITORENTER_opcode: { - if (ir.options.NO_SYNCHRO) { - inst.remove(); - } else { - Operand ref = MonitorOp.getClearRef(inst); - RVMType refType = ref.getType().peekType(); - if (refType != null && !refType.getThinLockOffset().isMax()) { - RVMMethod target = Entrypoints.inlineLockMethod; - Call.mutate2(inst, - CALL, - null, - IRTools.AC(target.getOffset()), - MethodOperand.STATIC(target), - MonitorOp.getClearGuard(inst), - ref, - IRTools.AC(refType.getThinLockOffset())); - if (inst.getBasicBlock().getInfrequent()) container.counter1++; - container.counter2++; - if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { - inline(inst, ir); - } - } else { - RVMMethod target = Entrypoints.lockMethod; - Call.mutate1(inst, - CALL, - null, - IRTools.AC(target.getOffset()), - MethodOperand.STATIC(target), - MonitorOp.getClearGuard(inst), - ref); + Operand ref = MonitorOp.getClearRef(inst); + RVMType refType = ref.getType().peekType(); + if (refType != null && !refType.getThinLockOffset().isMax()) { + RVMMethod target = Entrypoints.inlineLockMethod; + Call.mutate2(inst, + CALL, + null, + IRTools.AC(target.getOffset()), + MethodOperand.STATIC(target), + MonitorOp.getClearGuard(inst), + ref, + IRTools.AC(refType.getThinLockOffset())); + if (inst.getBasicBlock().getInfrequent()) container.counter1++; + container.counter2++; + if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { + inline(inst, ir); } + } else { + RVMMethod target = Entrypoints.lockMethod; + Call.mutate1(inst, + CALL, + null, + IRTools.AC(target.getOffset()), + MethodOperand.STATIC(target), + MonitorOp.getClearGuard(inst), + ref); } - break; } + break; case MONITOREXIT_opcode: { - if (ir.options.NO_SYNCHRO) { - inst.remove(); - } else { - Operand ref = MonitorOp.getClearRef(inst); - RVMType refType = ref.getType().peekType(); - if (refType != null && !refType.getThinLockOffset().isMax()) { - RVMMethod target = Entrypoints.inlineUnlockMethod; - Call.mutate2(inst, - CALL, - null, - IRTools.AC(target.getOffset()), - MethodOperand.STATIC(target), - MonitorOp.getClearGuard(inst), - ref, - IRTools.AC(refType.getThinLockOffset())); - if (inst.getBasicBlock().getInfrequent()) container.counter1++; - container.counter2++; - if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { - inline(inst, ir); - } - } else { - RVMMethod target = Entrypoints.unlockMethod; - Call.mutate1(inst, - CALL, - null, - IRTools.AC(target.getOffset()), - MethodOperand.STATIC(target), - MonitorOp.getClearGuard(inst), - ref); + Operand ref = MonitorOp.getClearRef(inst); + RVMType refType = ref.getType().peekType(); + if (refType != null && !refType.getThinLockOffset().isMax()) { + RVMMethod target = Entrypoints.inlineUnlockMethod; + Call.mutate2(inst, + CALL, + null, + IRTools.AC(target.getOffset()), + MethodOperand.STATIC(target), + MonitorOp.getClearGuard(inst), + ref, + IRTools.AC(refType.getThinLockOffset())); + if (inst.getBasicBlock().getInfrequent()) container.counter1++; + container.counter2++; + if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { + inline(inst, ir); } + } else { + RVMMethod target = Entrypoints.unlockMethod; + Call.mutate1(inst, + CALL, + null, + IRTools.AC(target.getOffset()), + MethodOperand.STATIC(target), + MonitorOp.getClearGuard(inst), + ref); } } break; Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-05 00:05:23 UTC (rev 15222) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-06 02:33:49 UTC (rev 15223) @@ -38,7 +38,7 @@ Compile the method assuming the invokee is thread-local NO_CALLEE_EXCEPTIONS -1 false -Assert that any callee of this compiled method will not throw exceptions? +Assert that any callee of this compiled method will not throw exceptions. Cannot be properly set on commandline SIMPLE_ESCAPE_IPA -1 false Eagerly compute method summaries for simple escape analysis @@ -118,39 +118,12 @@ SCHEDULE_PREPASS -1 false Perform prepass instruction scheduling -NO_CHECKCAST -1 false -Should all checkcast operations be (unsafely) eliminated? - -NO_CHECKSTORE -1 false -Should all checkstore operations be (unsafely) eliminated? - -NO_BOUNDS_CHECK -1 false -Should all bounds check operations be (unsafely) eliminated? - -NO_NULL_CHECK -1 false -Should all null check operations be (unsafely) eliminated? - -NO_SYNCHRO -1 false -Should all synchronization operations be (unsafely) eliminated? - -NO_THREADS -1 false -Should all yield points be (unsafely) eliminated? - -NO_CACHE_FLUSH -1 VM.BuildForIA32 -Should cache flush instructions (PowerPC SYNC/ISYNC) be omitted? NOTE: Cannot be correctly changed via the command line! - READS_KILL -1 false Should we constrain optimizations by enforcing reads-kill? -MONITOR_NOP -1 false -Should we treat all monitorenter/monitorexit bytecodes as nops? - STATIC_STATS -1 false Should we dump out compile-time statistics for basic blocks? -CODE_PATCH_NOP -1 false -Should all patch point be (unsafely) eliminated (at initial HIR)? - INSTRUMENTATION_SAMPLING -1 false Perform code transformation to sample instrumentation code. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-06 23:21:53
|
Revision: 15226 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15226&view=rev Author: captain5050 Date: 2008-12-06 23:21:47 +0000 (Sat, 06 Dec 2008) Log Message: ----------- RVM-725 WIP: make naming of opt compiler options more regular. Introduce options for local expression folding and tableswitch conversion. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/controller/AdaptiveInlining.java rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/DynamicCallGraphOrganizer.java rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/MutateSplits.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/CFGTransformations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/EstimateBlockFrequencies.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/depgraph/DepGraphStats.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/CompilerPhase.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/IRPrinter.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingBootImageCompiler.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingCompiler.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertHIRtoLIR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineDecision.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ConvertLIRtoMIR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/CoalesceMoves.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/specialization/InvokeeThreadLocalContext.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GCP.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GlobalCSE.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LICM.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LiveRangeSplitting.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoadElimination.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoopVersioning.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/PiNodes.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/RedundantBranchElimination.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat rvmroot/trunk/rvm/src-generated/options/ValueOptions.aos.dat rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/controller/AdaptiveInlining.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/controller/AdaptiveInlining.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/controller/AdaptiveInlining.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -39,7 +39,7 @@ // function for edge hotness. The intent is that early on // (until decay decreases this initial weight), we are conservative in // marking an edge as hot. - Controller.dcg = new PartialCallGraph(options.AI_SEED_MULTIPLIER * (1 / options.AI_HOT_CALLSITE_THRESHOLD)); + Controller.dcg = new PartialCallGraph(options.INLINE_AI_SEED_MULTIPLIER * (1 / options.INLINE_AI_HOT_CALLSITE_THRESHOLD)); RuntimeMeasurements.registerDecayableObject(Controller.dcg); // Track call density: fraction of timer interrupts taken in prologue/epilogue Modified: rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/DynamicCallGraphOrganizer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/DynamicCallGraphOrganizer.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/DynamicCallGraphOrganizer.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -112,7 +112,7 @@ * thresholdReachedCount * samplesPerInvocationOfThresholdReached > 1 / AI_HOT_CALLSITE_THRESHOLD * to be true. */ - thresholdReachedCount = (int)Math.ceil(1.0 /(numberOfBufferTriples * Controller.options.AI_HOT_CALLSITE_THRESHOLD));; + thresholdReachedCount = (int)Math.ceil(1.0 /(numberOfBufferTriples * Controller.options.INLINE_AI_HOT_CALLSITE_THRESHOLD));; // Install the edge listener if (Controller.options.cgTimer()) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -111,7 +111,7 @@ } public boolean shouldPerform(OptOptions options) { - return options.INSTRUMENTATION_SAMPLING; + return options.ADAPTIVE_INSTRUMENTATION_SAMPLING; } public String getName() { return "InstrumentationSamplingFramework"; } @@ -133,7 +133,7 @@ } // Perform the actual phase here. - if (ir.options.NO_DUPLICATION) { + if (ir.options.ADAPTIVE_NO_DUPLICATION) { performVariationNoDuplication(ir); } else { performVariationFullDuplication(ir, this); @@ -439,7 +439,7 @@ if (DEBUG) VM.sysWrite("Adding load to " + bb + "\n"); Instruction load = null; - if (ir.options.PROCESSOR_SPECIFIC_COUNTER) { + if (ir.options.ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER) { // Use one CBS counter per processor (better for multi threaded apps) if (ir.IRStage == IR.HIR) { @@ -495,7 +495,7 @@ if (DEBUG) VM.sysWrite("Adding store to " + bb + "\n"); Instruction store = null; - if (ir.options.PROCESSOR_SPECIFIC_COUNTER) { + if (ir.options.ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER) { store = Store.create(INT_STORE, cbsReg.copyRO(), @@ -589,7 +589,7 @@ dummy.insertBefore(load); // Store it in the counter register - if (ir.options.PROCESSOR_SPECIFIC_COUNTER) { + if (ir.options.ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER) { store = Store.create(INT_STORE, cbsReg.copyRO(), @@ -731,7 +731,7 @@ // been transfered to the duplicated code. for (InstructionEnumeration ie = origBlock.forwardInstrEnumerator(); ie.hasMoreElements();) { Instruction i = ie.next(); - if (isInstrumentationInstruction(i) || (isYieldpoint(i) && ir.options.REMOVE_YP_FROM_CHECKING)) { + if (isInstrumentationInstruction(i) || (isYieldpoint(i) && ir.options.ADAPTIVE_REMOVE_YP_FROM_CHECKING)) { if (DEBUG) VM.sysWrite("Removing " + i + "\n"); i.remove(); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/MutateSplits.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/MutateSplits.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/MutateSplits.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -41,7 +41,7 @@ } public boolean shouldPerform(OptOptions options) { - return options.LIVE_RANGE_SPLITTING; + return options.SSA_LIVE_RANGE_SPLITTING; } public String getName() { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -155,7 +155,7 @@ // if it does it will recompute it. foldConstants(ir); // Simple local expression folding respecting DU - if (false && ExpressionFolding.performLocal(ir)) { + if (ir.options.LOCAL_EXPRESSION_FOLDING && ExpressionFolding.performLocal(ir)) { // constant folding again foldConstants(ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -2023,7 +2023,7 @@ MethodOperand.STATIC(target), new IntConstantOperand(ref.getId()), receiver.copy()); - if (gc.options.NO_CALLEE_EXCEPTIONS) { + if (gc.options.H2L_NO_CALLEE_EXCEPTIONS) { callCheck.markAsNonPEI(); } @@ -2794,7 +2794,7 @@ int numHiddenParams = methOp.isStatic() ? 0 : 1; TypeReference[] params = meth.getParameterTypes(); Instruction s = Call.create(CALL, null, null, null, null, params.length + numHiddenParams); - if (gc.options.NO_CALLEE_EXCEPTIONS) { + if (gc.options.H2L_NO_CALLEE_EXCEPTIONS) { s.markAsNonPEI(); } for (int i = params.length - 1; i >= 0; i--) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerationContext.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -666,7 +666,7 @@ // since it's the second time reenter if (method.isForOsrSpecialization()) { // do nothing - } else if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { + } else if (method.isSynchronized() && !options.ESCAPE_INVOKEE_THREAD_LOCAL) { Operand lockObject = getLockObject(); Instruction s = MonitorOp.create(MONITORENTER, lockObject, new TrueGuardOperand()); appendInstruction(prologue, s, SYNCHRONIZED_MONITORENTER_BCI); @@ -679,7 +679,7 @@ */ private void completeEpilogue(boolean isOutermost) { // Deal with implicit monitorexit for synchronized methods. - if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { + if (method.isSynchronized() && !options.ESCAPE_INVOKEE_THREAD_LOCAL) { Operand lockObject = getLockObject(); Instruction s = MonitorOp.create(MONITOREXIT, lockObject, new TrueGuardOperand()); appendInstruction(epilogue, s, SYNCHRONIZED_MONITOREXIT_BCI); @@ -705,7 +705,7 @@ * PRECONDITION: cfg, arguments & temps have been setup/initialized. */ private void completeExceptionHandlers(boolean isOutermost) { - if (method.isSynchronized() && !options.INVOKEE_THREAD_LOCAL) { + if (method.isSynchronized() && !options.ESCAPE_INVOKEE_THREAD_LOCAL) { ExceptionHandlerBasicBlock rethrow = new ExceptionHandlerBasicBlock(SYNTH_CATCH_BCI, inlineSequence, Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -749,7 +749,7 @@ // evaluate whether it's profitable. int shortestCost = Math.min(takenCost, notTakenCost); int xformCost = 2 * (takenCost + notTakenCost); - int k = ir.options.COND_MOVE_CUTOFF; + int k = ir.options.CONTROL_COND_MOVE_CUTOFF; if (xformCost - shortestCost > k) return false; // Perform the transformation! Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/CFGTransformations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/CFGTransformations.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/CFGTransformations.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -84,7 +84,7 @@ if (options.getOptLevel() < 2) { return false; } - return options.TURN_WHILES_INTO_UNTILS; + return options.CONTROL_TURN_WHILES_INTO_UNTILS; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/EstimateBlockFrequencies.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/EstimateBlockFrequencies.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/EstimateBlockFrequencies.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -96,7 +96,7 @@ // Prepare ir = _ir; - if (ir.options.FREQUENCY_STRATEGY == OptOptions.DUMB_FREQ) { + if (ir.options.PROFILE_FREQUENCY_STRATEGY == OptOptions.PROFILE_DUMB_FREQ) { setDumbFrequencies(ir); return; } @@ -164,7 +164,7 @@ } // sort the frequencies (ascending); Arrays.sort(freq); - float f = ir.options.INFREQUENT_THRESHOLD; + float f = ir.options.PROFILE_INFREQUENT_THRESHOLD; float goal = (1f - f) * total; total = 0f; float threshold = 0f; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -85,14 +85,14 @@ } public boolean shouldPerform(OptOptions options) { - return ((options.getOptLevel() >= 3) && (options.UNROLL_LOG >= 1) && (!options.LOOP_VERSIONING)); + return ((options.getOptLevel() >= 3) && (options.CONTROL_UNROLL_LOG >= 1) && (!options.SSA_LOOP_VERSIONING)); } /** * This is the method that actually does the work of the phase. */ public void perform(IR ir) { - unrollFactor = (1 << ir.options.UNROLL_LOG); + unrollFactor = (1 << ir.options.CONTROL_UNROLL_LOG); if (ir.hasReachableExceptionHandlers()) return; DefUse.computeDU(ir); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -69,7 +69,7 @@ public String getName() { return "Static Splitting"; } public boolean shouldPerform(OptOptions options) { - return options.STATIC_SPLITTING; + return options.CONTROL_STATIC_SPLITTING; } public boolean printingEnabled(OptOptions options, boolean before) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/depgraph/DepGraphStats.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/depgraph/DepGraphStats.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/depgraph/DepGraphStats.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -105,7 +105,7 @@ } // Performing live analysis may reduce dependences between PEIs and stores - if (ir.options.HANDLER_LIVENESS) { + if (ir.options.L2M_HANDLER_LIVENESS) { new LiveAnalysis(false, false, true).perform(ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/CompilerPhase.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/CompilerPhase.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/CompilerPhase.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -208,7 +208,7 @@ if (ir.options.PRINT_ALL_IR || printingEnabled(ir.options, false)) { if (!ir.options.hasMETHOD_TO_PRINT() || ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) { // only print when above certain opt level - if (ir.options.getOptLevel() >= ir.options.IR_PRINT_LEVEL) { + if (ir.options.getOptLevel() >= ir.options.PRINT_IR_LEVEL) { dumpIR(ir, "After " + getName()); } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/IRPrinter.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/IRPrinter.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/IRPrinter.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -37,7 +37,7 @@ * @param ir the IR to print */ public final void perform(IR ir) { - if (ir.options.getOptLevel() < ir.options.IR_PRINT_LEVEL) { + if (ir.options.getOptLevel() < ir.options.PRINT_IR_LEVEL) { return; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingBootImageCompiler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingBootImageCompiler.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingBootImageCompiler.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -81,7 +81,7 @@ } } } - EdgeCounts.boot(masterOptions.EDGE_COUNT_INPUT_FILE); + EdgeCounts.boot(masterOptions.PROFILE_EDGE_COUNT_INPUT_FILE); OptimizingCompiler.init(masterOptions); } catch (OptimizingCompilerException e) { String msg = "BootImageCompiler: Compiler failed during initialization: " + e + "\n"; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingCompiler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingCompiler.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizingCompiler.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -69,7 +69,7 @@ // Make a local copy so that some options can be forced off just for the // duration of this initialization step. options = options.dup(); - options.SIMPLE_ESCAPE_IPA = false; + options.ESCAPE_SIMPLE_IPA = false; initializeStatics(); if (VM.runningVM) { @@ -122,7 +122,7 @@ // Only do guarded inlining if we can use code patches. // Early speculation with method test/class test can result in // bad code that we can't recover from later. - options.GUARDED_INLINE = options.guardWithCodePatch(); + options.INLINE_GUARDED = options.guardWithCodePatch(); // Compute summaries of bootimage methods if we haven't encountered them yet. // Does not handle unimplemented magics very well; disable until @@ -345,9 +345,9 @@ String msg = "Method throws NoOptCompilePragma"; throw MagicNotImplementedException.EXPECTED(msg); } - if (options.hasEXCLUDE()) { + if (options.hasDRIVER_EXCLUDE()) { String name = method.getDeclaringClass().toString() + "." + method.getName(); - if (options.fuzzyMatchEXCLUDE(name)) { + if (options.fuzzyMatchDRIVER_EXCLUDE(name)) { if (!method.getDeclaringClass().hasSaveVolatileAnnotation()) { throw new OptimizingCompilerException("method excluded", false); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -66,7 +66,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.MONITOR_REMOVAL || options.SCALAR_REPLACE_AGGREGATES; + return options.ESCAPE_MONITOR_REMOVAL || options.ESCAPE_SCALAR_REPLACE_AGGREGATES; } public final String getName() { @@ -109,7 +109,7 @@ // of aggregates // ********************************************************* Instruction def = reg.defList.instruction; - if (ir.options.SCALAR_REPLACE_AGGREGATES && summary.isMethodLocal(reg)) { + if (ir.options.ESCAPE_SCALAR_REPLACE_AGGREGATES && summary.isMethodLocal(reg)) { AggregateReplacer s = null; if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { s = getAggregateReplacer(def, ir); @@ -123,7 +123,7 @@ // ********************************************************* // Now remove synchronizations // ********************************************************* - if (ir.options.MONITOR_REMOVAL && summary.isThreadLocal(reg)) { + if (ir.options.ESCAPE_MONITOR_REMOVAL && summary.isThreadLocal(reg)) { UnsyncReplacer unsync = null; if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { unsync = getUnsyncReplacer(reg, def, ir); @@ -222,11 +222,11 @@ } // first attempt to perform scalar replacement for an object - if (t.isClassType() && options.SCALAR_REPLACE_AGGREGATES) { + if (t.isClassType() && options.ESCAPE_SCALAR_REPLACE_AGGREGATES) { return ObjectReplacer.getReplacer(inst, ir); } // attempt to perform scalar replacement on a short array - if (t.isArrayType() && options.SCALAR_REPLACE_AGGREGATES) { + if (t.isArrayType() && options.ESCAPE_SCALAR_REPLACE_AGGREGATES) { return ShortArrayReplacer.getReplacer(inst, ir); } return null; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -173,7 +173,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.SIMPLE_ESCAPE_IPA; + return options.ESCAPE_SIMPLE_IPA; } public final String getName() { @@ -774,7 +774,7 @@ private static MethodSummary findOrCreateMethodSummary(RVMMethod m, OptOptions options) { MethodSummary summ = SummaryDatabase.findMethodSummary(m); if (summ == null) { - if (options.SIMPLE_ESCAPE_IPA) { + if (options.ESCAPE_SIMPLE_IPA) { performSimpleEscapeAnalysis(m, options); summ = SummaryDatabase.findMethodSummary(m); } @@ -788,7 +788,7 @@ * Perform the simple escape analysis for a method. */ private static void performSimpleEscapeAnalysis(RVMMethod m, OptOptions options) { - if (!options.SIMPLE_ESCAPE_IPA) { + if (!options.ESCAPE_SIMPLE_IPA) { return; } // do not perform for unloaded methods Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertHIRtoLIR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertHIRtoLIR.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertHIRtoLIR.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -34,7 +34,7 @@ if (IR.SANITY_CHECK) { ir.verify("before conversion to LIR", true); } - if (ir.options.STATIC_STATS) { + if (ir.options.PRINT_STATIC_STATS) { // Print summary statistics (critpath, etc.) for all basic blocks DepGraphStats.printBasicBlockStatistics(ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -444,7 +444,7 @@ } Operand val = TableSwitch.getClearValue(s); BranchOperand defaultLabel = TableSwitch.getClearDefault(s); - if (number < 8) { // convert into a lookupswitch + if (number < ir.options.CONTROL_TABLESWITCH_CUTOFF) { // convert into a lookupswitch Instruction l = LookupSwitch.create(LOOKUPSWITCH, val, Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -169,7 +169,7 @@ offset, site); next = inst.prevInstructionInCodeOrder(); - if (ir.options.INLINE_NEW) { + if (ir.options.H2L_INLINE_NEW) { if (inst.getBasicBlock().getInfrequent()) container.counter1++; container.counter2++; if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { @@ -227,7 +227,7 @@ offset, site); next = inst.prevInstructionInCodeOrder(); - if (inline && ir.options.INLINE_NEW) { + if (inline && ir.options.H2L_INLINE_NEW) { if (inst.getBasicBlock().getInfrequent()) container.counter1++; container.counter2++; if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) { @@ -385,7 +385,7 @@ wb.position = inst.position; inst.replace(wb); next = wb.prevInstructionInCodeOrder(); - if (ir.options.INLINE_WRITE_BARRIER) { + if (ir.options.H2L_INLINE_WRITE_BARRIER) { inline(wb, ir, true); } } @@ -434,7 +434,7 @@ wb.position = inst.position; inst.replace(wb); next = wb.prevInstructionInCodeOrder(); - if (ir.options.INLINE_WRITE_BARRIER) { + if (ir.options.H2L_INLINE_WRITE_BARRIER) { inline(wb, ir, true); } } @@ -489,7 +489,7 @@ wb.position = inst.position; inst.replace(wb); next = wb.prevInstructionInCodeOrder(); - if (ir.options.INLINE_WRITE_BARRIER) { + if (ir.options.H2L_INLINE_WRITE_BARRIER) { inline(wb, ir, true); } } @@ -556,9 +556,9 @@ // so we have to be sure to inline it "all the way" not // just 1 level. boolean savedInliningOption = ir.options.INLINE; - boolean savedExceptionOption = ir.options.NO_CALLEE_EXCEPTIONS; + boolean savedExceptionOption = ir.options.H2L_NO_CALLEE_EXCEPTIONS; ir.options.INLINE = true; - ir.options.NO_CALLEE_EXCEPTIONS = noCalleeExceptions; + ir.options.H2L_NO_CALLEE_EXCEPTIONS = noCalleeExceptions; boolean savedOsrGI = ir.options.OSR_GUARDED_INLINING; ir.options.OSR_GUARDED_INLINING = false; try { @@ -567,7 +567,7 @@ Inliner.execute(inlDec, ir, inst); } finally { ir.options.INLINE = savedInliningOption; - ir.options.NO_CALLEE_EXCEPTIONS = savedExceptionOption; + ir.options.H2L_NO_CALLEE_EXCEPTIONS = savedExceptionOption; ir.options.OSR_GUARDED_INLINING = savedOsrGI; } didSomething = true; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -89,7 +89,7 @@ if (!staticCallee.isAbstract()) { int inlinedSizeEstimate = inlinedSizeEstimate((NormalMethod) staticCallee, state); boolean guardless = state.getHasPreciseTarget() || !needsGuard(staticCallee); - if (inlinedSizeEstimate < opts.IC_MAX_ALWAYS_INLINE_TARGET_SIZE && + if (inlinedSizeEstimate < opts.INLINE_MAX_ALWAYS_INLINE_TARGET_SIZE && guardless && !state.getSequence().containsMethod(staticCallee)) { if (verbose) VM.sysWriteln("\tYES: trivial guardless inline\n"); @@ -104,7 +104,7 @@ return InlineDecision.NO("Only do trivial inlines at O0"); } - if (rootMethod.inlinedSizeEstimate() > opts.IC_MASSIVE_METHOD_SIZE) { + if (rootMethod.inlinedSizeEstimate() > opts.INLINE_MASSIVE_METHOD_SIZE) { // In massive methods, we do not do any additional inlining to // avoid completely blowing out compile time by making a bad situation worse if (verbose) VM.sysWriteln("\tNO: only do trivial inlines into massive methods\n"); @@ -147,7 +147,7 @@ // Fake up "profile data" based on static information to // be able to share all the decision making logic. if (state.isInvokeInterface()) { - if (opts.GUARDED_INLINE_INTERFACE) { + if (opts.INLINE_GUARDED_INTERFACES) { RVMMethod singleImpl = InterfaceHierarchy.getUniqueImplementation(staticCallee); if (singleImpl != null && hasBody(singleImpl)) { if (verbose) { @@ -229,9 +229,9 @@ } boolean currentlyFinal = (goosc || (staticCallee == callee)) && isCurrentlyFinal(callee, !opts.guardWithClassTest()); - boolean preEx = needsGuard && state.getIsExtant() && opts.PREEX_INLINE && currentlyFinal; + boolean preEx = needsGuard && state.getIsExtant() && opts.INLINE_PREEX && currentlyFinal; if (needsGuard && !preEx) { - if (!opts.GUARDED_INLINE) { + if (!opts.INLINE_GUARDED) { if (verbose) VM.sysWriteln("\t\tReject: guarded inlining disabled"); return; } @@ -263,18 +263,18 @@ if (!decideYes) { int inlinedSizeEstimate = inlinedSizeEstimate((NormalMethod) callee, state); int cost = inliningActionCost(inlinedSizeEstimate, needsGuard, preEx, opts); - int maxCost = opts.IC_MAX_TARGET_SIZE; + int maxCost = opts.INLINE_MAX_TARGET_SIZE; - if (callSiteWeight > Controller.options.AI_SEED_MULTIPLIER) { + if (callSiteWeight > Controller.options.INLINE_AI_SEED_MULTIPLIER) { // real profile data with enough samples for us to trust it. // Use weight and shape of call site distribution to compute // a higher maxCost. double fractionOfSample = weight / callSiteWeight; - if (needsGuard && fractionOfSample < opts.AI_MIN_CALLSITE_FRACTION) { - // This call accounts for less than AI_MIN_CALLSITE_FRACTION + if (needsGuard && fractionOfSample < opts.INLINE_AI_MIN_CALLSITE_FRACTION) { + // This call accounts for less than INLINE_AI_MIN_CALLSITE_FRACTION // of the profiled targets at this call site. // It is highly unlikely to be profitable to inline it. - if (verbose) VM.sysWriteln("\t\tReject: less than AI_MIN_CALLSITE_FRACTION of distribution"); + if (verbose) VM.sysWriteln("\t\tReject: less than INLINE_AI_MIN_CALLSITE_FRACTION of distribution"); maxCost = 0; } else { if (cost > maxCost) { @@ -283,19 +283,19 @@ * dynamic call graph) the edge is. */ double adjustedWeight = AdaptiveInlining.adjustedWeight(weight); - if (adjustedWeight > Controller.options.AI_HOT_CALLSITE_THRESHOLD) { + if (adjustedWeight > Controller.options.INLINE_AI_HOT_CALLSITE_THRESHOLD) { /* A truly hot edge; use the max allowable callee size */ - maxCost = opts.AI_MAX_TARGET_SIZE; + maxCost = opts.INLINE_AI_MAX_TARGET_SIZE; } else { /* A warm edge, we will use a value between the static default and the max allowable. * The code below simply does a linear interpolation between 2x static default * and max allowable. * Other alternatives would be to do a log interpolation or some other step function. */ - int range = opts.AI_MAX_TARGET_SIZE - 2*opts.IC_MAX_TARGET_SIZE; - double slope = ((double) range) / Controller.options.AI_HOT_CALLSITE_THRESHOLD; + int range = opts.INLINE_AI_MAX_TARGET_SIZE - 2*opts.INLINE_MAX_TARGET_SIZE; + double slope = ((double) range) / Controller.options.INLINE_AI_HOT_CALLSITE_THRESHOLD; int scaledAdj = (int) (slope * adjustedWeight); - maxCost += opts.IC_MAX_TARGET_SIZE + scaledAdj; + maxCost += opts.INLINE_MAX_TARGET_SIZE + scaledAdj; } } } @@ -303,8 +303,8 @@ // Somewhat bogus, but if we get really deeply inlined we start backing off. int curDepth = state.getInlineDepth(); - if (curDepth > opts.IC_MAX_INLINE_DEPTH) { - maxCost /= (curDepth - opts.IC_MAX_INLINE_DEPTH + 1); + if (curDepth > opts.INLINE_MAX_INLINE_DEPTH) { + maxCost /= (curDepth - opts.INLINE_MAX_INLINE_DEPTH + 1); } decideYes = cost <= maxCost; @@ -352,9 +352,9 @@ if ((guardOverrideOnStaticCallee || target == staticCallee) && isCurrentlyFinal(target, !opts.guardWithClassTest())) { InlineDecision d = - InlineDecision.guardedYES(target, - chooseGuard(caller, target, staticCallee, state, true), - "Guarded inline of single static target"); + InlineDecision.guardedYES(target, + chooseGuard(caller, target, staticCallee, state, true), + "Guarded inline of single static target"); /* * Determine if it is allowable to put an OSR point in the failed case of * the guarded inline instead of generating a real call instruction. @@ -377,9 +377,9 @@ return d; } else { InlineDecision d = - InlineDecision.guardedYES(target, - chooseGuard(caller, target, staticCallee, state, false), - "Guarded inlining of one potential target"); + InlineDecision.guardedYES(target, + chooseGuard(caller, target, staticCallee, state, false), + "Guarded inlining of one potential target"); if (verbose) VM.sysWriteln("\tDecide: " + d); return d; } @@ -433,25 +433,25 @@ */ private byte chooseGuard(RVMMethod caller, RVMMethod singleImpl, RVMMethod callee, CompilationState state, boolean codePatchSupported) { - byte guard = state.getOptions().INLINING_GUARD; + byte guard = state.getOptions().INLINE_GUARD_KIND; if (codePatchSupported) { if (VM.VerifyAssertions && VM.runningVM) { VM._assert(ObjectModel.holdsLock(RVMClass.classLoadListener, Scheduler.getCurrentThread())); } - if (guard == OptOptions.IG_CODE_PATCH) { + if (guard == OptOptions.INLINE_GUARD_CODE_PATCH) { ClassLoadingDependencyManager cldm = (ClassLoadingDependencyManager) RVMClass.classLoadListener; if (ClassLoadingDependencyManager.TRACE || ClassLoadingDependencyManager.DEBUG) { cldm.report("CODE PATCH: Inlined " + singleImpl + " into " + caller + "\n"); } cldm.addNotOverriddenDependency(callee, state.getCompiledMethod()); } - } else if (guard == OptOptions.IG_CODE_PATCH) { - guard = OptOptions.IG_METHOD_TEST; + } else if (guard == OptOptions.INLINE_GUARD_CODE_PATCH) { + guard = OptOptions.INLINE_GUARD_METHOD_TEST; } - if (guard == OptOptions.IG_METHOD_TEST && singleImpl.getDeclaringClass().isFinal()) { + if (guard == OptOptions.INLINE_GUARD_METHOD_TEST && singleImpl.getDeclaringClass().isFinal()) { // class test is more efficient and just as effective - guard = OptOptions.IG_CLASS_TEST; + guard = OptOptions.INLINE_GUARD_CLASS_TEST; } return guard; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineDecision.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineDecision.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineDecision.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -191,13 +191,13 @@ s += " " + targets[i]; if (guards != null) { switch (guards[i]) { - case OptOptions.IG_METHOD_TEST: + case OptOptions.INLINE_GUARD_METHOD_TEST: s += " (method test)"; break; - case OptOptions.IG_CLASS_TEST: + case OptOptions.INLINE_GUARD_CLASS_TEST: s += " (class test)"; break; - case OptOptions.IG_CODE_PATCH: + case OptOptions.INLINE_GUARD_CODE_PATCH: s += " (code patch)"; break; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -159,7 +159,7 @@ NormalMethod callee = (NormalMethod) targets[i]; // (a) if (parent.options.PRINT_INLINE_REPORT) { - String guard = guards[i] == OptOptions.IG_CLASS_TEST ? " (class test) " : " (method test) "; + String guard = guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST ? " (class test) " : " (method test) "; VM.sysWrite("\tGuarded inline" + guard + " " + callee + " into " + callSite.position.getMethod() + " at bytecode " + callSite.bcIndex + "\n"); @@ -360,7 +360,7 @@ } } - if (guards[i] == OptOptions.IG_CLASS_TEST) { + if (guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST) { tmp = InlineGuard.create(IG_CLASS_TEST, receiver.copy(), @@ -368,7 +368,7 @@ new TypeOperand(target.getDeclaringClass()), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely()); - } else if (guards[i] == OptOptions.IG_METHOD_TEST) { + } else if (guards[i] == OptOptions.INLINE_GUARD_METHOD_TEST) { // method test for interface requires additional check if // the reciever's class is a subclass of inlined method's // declaring class. Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ConvertLIRtoMIR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ConvertLIRtoMIR.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ConvertLIRtoMIR.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -352,7 +352,7 @@ } public void perform(IR ir) { - if (ir.options.HANDLER_LIVENESS) { + if (ir.options.L2M_HANDLER_LIVENESS) { new LiveAnalysis(false, false, true).perform(ir); } else { ir.setHandlerLivenessComputed(false); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/CoalesceMoves.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/CoalesceMoves.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/CoalesceMoves.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -50,7 +50,7 @@ * @param options controlling compiler options */ public final boolean shouldPerform(OptOptions options) { - return options.COALESCE_AFTER_SSA; + return options.SSA_COALESCE_AFTER; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -940,14 +940,14 @@ this.ir = ir; this.spillManager = sm; - switch (ir.options.SPILL_COST_ESTIMATE) { - case OptOptions.SIMPLE_SPILL_COST: + switch (ir.options.REGALLOC_SPILL_COST_ESTIMATE) { + case OptOptions.REGALLOC_SIMPLE_SPILL_COST: spillCost = new SimpleSpillCost(ir); break; - case OptOptions.BRAINDEAD_SPILL_COST: + case OptOptions.REGALLOC_BRAINDEAD_SPILL_COST: spillCost = new BrainDeadSpillCost(ir); break; - case OptOptions.BLOCK_COUNT_SPILL_COST: + case OptOptions.REGALLOC_BLOCK_COUNT_SPILL_COST: spillCost = new BlockCountSpillCost(ir); break; default: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/specialization/InvokeeThreadLocalContext.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/specialization/InvokeeThreadLocalContext.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/specialization/InvokeeThreadLocalContext.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -89,7 +89,8 @@ public static void init() { options = new OptOptions(); optimizationPlan = OptimizationPlanner.createOptimizationPlan(options); - options.INVOKEE_THREAD_LOCAL = true; + // all objects in the specialized method will be thread local + options.ESCAPE_INVOKEE_THREAD_LOCAL = true; } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GCP.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GCP.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GCP.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -66,7 +66,7 @@ if (options.getOptLevel() < 2) { return false; } - return options.GCP || options.VERBOSE_GCP || options.GCSE; + return options.SSA_GCP || options.SSA_GCSE; } static boolean tooBig(IR ir) { @@ -97,7 +97,7 @@ * @param options */ public final boolean shouldPerform(OptOptions options) { - return options.GCP || options.VERBOSE_GCP || options.GCSE; + return options.SSA_GCP || options.SSA_GCSE; } /** @@ -139,7 +139,7 @@ ir.desiredSSAOptions.setScalarsOnly(false); ir.desiredSSAOptions.setBackwards(true); ir.desiredSSAOptions.setInsertUsePhis(true); - ir.desiredSSAOptions.setInsertPEIDeps(!ir.options.LICM_IGNORE_PEI); + ir.desiredSSAOptions.setInsertPEIDeps(!ir.options.SSA_LICM_IGNORE_PEI); ir.desiredSSAOptions.setHeapTypes(null); } } @@ -164,7 +164,7 @@ * @param options */ public final boolean shouldPerform(OptOptions options) { - return options.GCP || options.VERBOSE_GCP || options.GCSE; + return options.SSA_GCP || options.SSA_GCSE; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GlobalCSE.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GlobalCSE.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/GlobalCSE.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -76,7 +76,7 @@ * unless we pass through this test. */ public boolean shouldPerform(OptOptions options) { - return options.GCSE; + return options.SSA_GCSE; } /** @@ -108,7 +108,7 @@ return; } // cache useful values - verbose = ir.options.VERBOSE_GCP; + verbose = ir.options.DEBUG_GCP; this.ir = ir; dominator = ir.HIRInfo.dominatorTree; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LICM.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LICM.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LICM.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -100,7 +100,7 @@ return; } - VERBOSE = ir.options.VERBOSE_GCP; + VERBOSE = ir.options.DEBUG_GCP; if (VERBOSE && ir.options.hasMETHOD_TO_PRINT()) { VERBOSE = ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString()); @@ -145,7 +145,7 @@ * @param options */ public boolean shouldPerform(OptOptions options) { - return options.GCP || options.VERBOSE_GCP; + return options.SSA_GCP; } //------------------------- Implementation ------------------------- @@ -340,7 +340,7 @@ } /* don't put memory stores or PEIs on speculative path */ - if ((inst.isPEI() && !ir.options.LICM_IGNORE_PEI) || inst.isImplicitStore()) { + if ((inst.isPEI() && !ir.options.SSA_LICM_IGNORE_PEI) || inst.isImplicitStore()) { while (!postDominates(getBlock(inst), getBlock(_earlyPos))) { _earlyPos = dominanceSuccessor(_earlyPos, inst); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LiveRangeSplitting.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LiveRangeSplitting.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LiveRangeSplitting.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -63,7 +63,7 @@ public class LiveRangeSplitting extends OptimizationPlanCompositeElement { public final boolean shouldPerform(OptOptions options) { - return options.LIVE_RANGE_SPLITTING; + return options.SSA_LIVE_RANGE_SPLITTING; } /** @@ -98,7 +98,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.LIVE_RANGE_SPLITTING; + return options.SSA_LIVE_RANGE_SPLITTING; } public final String getName() { @@ -393,7 +393,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.LIVE_RANGE_SPLITTING; + return options.SSA_LIVE_RANGE_SPLITTING; } public final String getName() { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoadElimination.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoadElimination.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoadElimination.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -94,7 +94,7 @@ static final boolean DEBUG = false; public boolean shouldPerform(OptOptions options) { - return options.LOAD_ELIMINATION; + return options.SSA_LOAD_ELIMINATION; } public String getName() { @@ -680,7 +680,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.LOAD_ELIMINATION; + return options.SSA_LOAD_ELIMINATION; } public final String getName() { @@ -697,7 +697,7 @@ ir.desiredSSAOptions.setBackwards(false); ir.desiredSSAOptions.setInsertUsePhis(true); ir.desiredSSAOptions.setHeapTypes(LoadElimination.getCandidates(ir)); - ir.desiredSSAOptions.setAbort((round > ir.options.LOAD_ELIMINATION_ROUNDS) || + ir.desiredSSAOptions.setAbort((round > ir.options.SSA_LOAD_ELIMINATION_ROUNDS) || (!ir.HIRInfo.loadEliminationDidSomething)); } } @@ -708,7 +708,7 @@ private static class GVNPreparation extends CompilerPhase { public final boolean shouldPerform(OptOptions options) { - return options.LOAD_ELIMINATION; + return options.SSA_LOAD_ELIMINATION; } public final String getName() { @@ -746,7 +746,7 @@ ir.desiredSSAOptions.setScalarsOnly(true); ir.desiredSSAOptions.setBackwards(false); ir.desiredSSAOptions.setInsertUsePhis(false); - ir.desiredSSAOptions.setAbort((round > ir.options.LOAD_ELIMINATION_ROUNDS) || + ir.desiredSSAOptions.setAbort((round > ir.options.SSA_LOAD_ELIMINATION_ROUNDS) || (!ir.HIRInfo.loadEliminationDidSomething)); } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoopVersioning.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoopVersioning.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LoopVersioning.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -344,7 +344,7 @@ */ @Override public boolean shouldPerform(OptOptions options) { - return options.LOOP_VERSIONING; + return options.SSA_LOOP_VERSIONING; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/PiNodes.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/PiNodes.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/PiNodes.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -70,7 +70,7 @@ * @param options controlling compiler options */ public boolean shouldPerform(OptOptions options) { - return options.GLOBAL_BOUNDS_CHECK || typeChecks; + return options.SSA_GLOBAL_BOUNDS_CHECK || typeChecks; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/RedundantBranchElimination.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/RedundantBranchElimination.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/RedundantBranchElimination.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -61,7 +61,7 @@ public final class RedundantBranchElimination extends OptimizationPlanCompositeElement { public boolean shouldPerform(OptOptions options) { - return options.REDUNDANT_BRANCH_ELIMINATION; + return options.SSA_REDUNDANT_BRANCH_ELIMINATION; } /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java 2008-12-06 23:21:47 UTC (rev 15226) @@ -67,7 +67,7 @@ } public final boolean shouldPerform(OptOptions options) { - return options.SSA && options.EXPRESSION_FOLDING; + return options.SSA && options.SSA_EXPRESSION_FOLDING; } public final String getName() { Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-06 23:16:27 UTC (rev 15225) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-06 23:21:47 UTC (rev 15226) @@ -15,9 +15,38 @@ DESCRIP ########## -# First all the non-printing, non-debugging options -# Should not start with PRINT_ or DEBUG_ prefix +# Cross cutting optimization options ########## +FREQ_FOCUS_EFFORT -1 false focus_effort +Focus compilation effort based on frequency profile data + +READS_KILL -1 false +Should we constrain optimizations by enforcing reads-kill? + +########## +# Analysis of fields to help determine their type options +########## +FIELD_ANALYSIS 0 true +Eagerly compute method summaries for flow-insensitive field analysis + +########## +# Inlining optimizations +########## +INLINE 0 true +Inline statically resolvable calls + +INLINE_GUARDED 0 true +Guarded inlining of non-final virtual calls + +INLINE_GUARDED_INTERFACES 0 true +Speculatively inline non-final interface calls + +INLINE_PREEX 0 true +Pre-existence based inlining + +########## +# Local (within a basic block) optimizations +########## LOCAL_CONSTANT_PROP 0 true Perform local constant propagation @@ -27,126 +56,132 @@ LOCAL_CSE 0 true Perform local common subexpression elimination -# ABCD is currently incomplete; it doesn't check lower bounds -GLOBAL_BOUNDS_CHECK -1 false global_bounds -Perform global Array Bound Check elimination on Demand +LOCAL_EXPRESSION_FOLDING 3 false +Should we try to fold expressions with constants locally? -MONITOR_REMOVAL 1 true -Try to remove unnecessary monitor operations +########## +# Control-flow optimization options +########## +CONTROL_STATIC_SPLITTING 1 true +CFG splitting to create hot traces based on static heuristics -INVOKEE_THREAD_LOCAL -1 false -Compile the method assuming the invokee is thread-local +CONTROL_TURN_WHILES_INTO_UNTILS 3 false control_unwhile +Turn whiles into untils -NO_CALLEE_EXCEPTIONS -1 false -Assert that any callee of this compiled method will not throw exceptions. Cannot be properly set on commandline - -SIMPLE_ESCAPE_IPA -1 false +########## +# Simple escape optimization options +########## +ESCAPE_SIMPLE_IPA -1 false Eagerly compute method summaries for simple escape analysis -FIELD_ANALYSIS 0 true -Eagerly compute method summaries for flow-insensitive field analysis +ESCAPE_SCALAR_REPLACE_AGGREGATES 1 true +If possible turn aggregates (objects) into variable definition/uses -SCALAR_REPLACE_AGGREGATES 1 true -Perform scalar replacement of aggregates +ESCAPE_MONITOR_REMOVAL 1 true +Try to remove unnecessary monitor operations -REORDER_CODE 0 true -Reorder basic blocks for improved locality and branch prediction +ESCAPE_INVOKEE_THREAD_LOCAL -1 false +Compile the method assuming the invokee is thread-local. Cannot be properly set on command line. -REORDER_CODE_PH 1 true -Reorder basic blocks using Pettis and Hansen Algo2 +########## +# SSA optimizations +########## +SSA 3 false +Should SSA form be constructed on the HIR? -INLINE_NEW 0 true -Inline allocation of scalars and arrays +SSA_EXPRESSION_FOLDING 3 false +Should we try to fold expressions with constants in SSA form? -INLINE_WRITE_BARRIER 1 true -Inline write barriers for generational collectors - -INLINE 0 true -Inline statically resolvable calls - -GUARDED_INLINE 0 true -Guarded inlining of non-final virtual calls - -GUARDED_INLINE_INTERFACE 0 true -Speculatively inline non-final interface calls - -STATIC_SPLITTING 1 true -CFG splitting to create hot traces based on static heuristics - -REDUNDANT_BRANCH_ELIMINATION 3 true +SSA_REDUNDANT_BRANCH_ELIMINATION 3 true Eliminate redundant conditional branches -PREEX_INLINE 0 true -Pre-existence based inlining +# This options looks unsound, remove? +SSA_LICM_IGNORE_PEI -1 false +Assume PEIs do not throw or state is not observable -SSA 3 false -Should SSA form be constructed on the HIR? - -LOAD_ELIMINATION 3 false +SSA_LOAD_ELIMINATION 3 false Should we perform redundant load elimination during SSA pass? -COALESCE_AFTER_SSA 3 false +SSA_COALESCE_AFTER 3 false Should we coalesce move instructions after leaving SSA? -EXPRESSION_FOLDING 3 false -Should we try to fold expressions with constants in SSA form? +SSA_LOOP_VERSIONING -1 false +Create copies of loops where runtime exceptions are checked prior to entry -LIVE_RANGE_SPLITTING -1 false +SSA_LIVE_RANGE_SPLITTING -1 false Split live ranges using LIR SSA pass? -GCP 3 false gcp +SSA_GCP 3 false Perform global code placement -GCSE 3 false gcse +SSA_GCSE 3 false Perform global code placement -VERBOSE_GCP -1 false verbose_gcp -Perform noisy global code placement +# ABCD is currently incomplete; it doesn't check lower bounds +SSA_GLOBAL_BOUNDS_CHECK -1 false ssa_global_bounds +Perform (incomplete/unsafe) global Array Bound Check elimination on Demand -LICM_IGNORE_PEI -1 false licm_ignore_pei -Asume PEIs do not throw or state is not observable +########## +# Code reordering for icache performance options +########## +REORDER_CODE 0 true +Reorder basic blocks for improved locality and branch prediction -TURN_WHILES_INTO_UNTILS 3 false unwhile -Turn whiles into untils +REORDER_CODE_PH 1 true +Reorder basic blocks using Pettis and Hansen Algo2 -LOOP_VERSIONING -1 false loop_versioning -Loop versioning +########## +# Options during conversion from HIR to LIR +########## +H2L_INLINE_NEW 0 true +Inline allocation of scalars and arrays -HANDLER_LIVENESS 2 false +H2L_INLINE_WRITE_BARRIER 1 true +Inline write barriers for generational collectors + +H2L_NO_CALLEE_EXCEPTIONS -1 false +Assert that any callee of this compiled method will not throw exceptions. Cannot be properly set on command line. + +########## +# Options during conversion from LIR to MIR +########## +L2M_HANDLER_LIVENESS 2 false Store liveness for handlers to improve dependence graph at PEIs -SCHEDULE_PREPASS -1 false +L2M_SCHEDULE_PREPASS -1 false Perform prepass instruction scheduling -READS_KILL -1 false -Should we constrain optimizations by enforcing reads-kill? - -STATIC_STATS -1 false -Should we dump out compile-time statistics for basic blocks? - -INSTRUMENTATION_SAMPLING -1 false +########## +# Options for adaptive compilation +########## +ADAPTIVE_INSTRUMENTATION_SAMPLING -1 false Perform code transformation to sample instrumentation code. -NO_DUPLICATION -1 false +ADAPTIVE_NO_DUPLICATION -1 false When performing inst. sampling, should it be done without duplicating code? -PROCESSOR_SPECIFIC_COUNTER -1 true +ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER -1 true Should there be one CBS counter per processor for SMP performance? -REMOVE_YP_FROM_CHECKING -1 false +ADAPTIVE_REMOVE_YP_FROM_CHECKING -1 ... [truncated message content] |
From: <cap...@us...> - 2008-12-07 00:21:34
|
Revision: 15227 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15227&view=rev Author: captain5050 Date: 2008-12-07 00:21:29 +0000 (Sun, 07 Dec 2008) Log Message: ----------- RVM-725 WIP: introduce new options to control bonuses given to reduce the method size when particular arguments are passed to a method being considered for inlining. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java 2008-12-06 23:21:47 UTC (rev 15226) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java 2008-12-07 00:21:29 UTC (rev 15227) @@ -24,6 +24,7 @@ import org.jikesrvm.compilers.opt.ir.Instruction; import org.jikesrvm.compilers.opt.ir.operand.Operand; import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand; +import org.jikesrvm.compilers.opt.OptOptions; import org.jikesrvm.runtime.Entrypoints; import org.vmmagic.pragma.Inline; @@ -119,6 +120,7 @@ Instruction callInstr = state.getCallInstruction(); int numArgs = Call.getNumberOfParams(callInstr); double reductionFactor = 1.0; // no reduction. + OptOptions opts = state.getOptions(); for (int i = 0; i < numArgs; i++) { Operand op = Call.getParam(callInstr, i); if (op instanceof RegisterOperand) { @@ -128,28 +130,29 @@ if (type.isArrayType()) { // Reductions only come from optimization of dynamic type checks; all virtual methods on arrays are defined on Object. if (rop.isPreciseType()) { - reductionFactor -= 0.05; + reductionFactor -= opts.INLINE_PRECISE_REG_ARRAY_ARG_BONUS; } else if (rop.isDeclaredType() && callee.hasArrayWrite() && type.getArrayElementType().isReferenceType()) { - reductionFactor -= 0.02; // potential to optimize checkstore portion of aastore bytecode on parameter + // potential to optimize checkstore portion of aastore bytecode on parameter + reductionFactor -= opts.INLINE_DECLARED_AASTORED_ARRAY_ARG_BONUS; } } else { // Reductions come from optimization of dynamic type checks and improved inlining of virtual/interface calls if (rop.isPreciseType()) { - reductionFactor -= 0.15; + reductionFactor -= opts.INLINE_PRECISE_REG_CLASS_ARG_BONUS; } else if (rop.isExtant()) { - reductionFactor -= 0.05; + reductionFactor -= opts.INLINE_EXTANT_REG_CLASS_ARG_BONUS; } } } } else if (op.isIntConstant()) { - reductionFactor -= 0.05; // 5% credit for being an int constant; mainly in the hopes of control flow simplifications + reductionFactor -= opts.INLINE_INT_CONST_ARG_BONUS; } else if (op.isNullConstant()) { - reductionFactor -= 0.10; // 10% credit for being 'null' as this enables a number of simplifications + reductionFactor -= opts.INLINE_NULL_CONST_ARG_BONUS; } else if (op.isObjectConstant()) { - reductionFactor -= 0.10; // 10% credit for being a string/class/object constant: inlining, constant folding, and Pure method opportunities + reductionFactor -= opts.INLINE_OBJECT_CONST_ARG_BONUS; } } - reductionFactor = Math.max(reductionFactor, 0.60); // bound credits at 40% off; we don't want to be too optimistic about code space reductions. + reductionFactor = Math.max(reductionFactor, 1.0-opts.INLINE_MAX_ARG_BONUS); return (int) (sizeEstimate * reductionFactor); } Modified: rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-06 23:21:47 UTC (rev 15226) +++ rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-07 00:21:29 UTC (rev 15227) @@ -83,6 +83,44 @@ Static inlining heuristic: If root method is already this big, then only inline trivial methods +# bound credits at 40% off; we don't want to be too optimistic about code space reductions. +V INLINE_MAX_ARG_BONUS double 0.40 +Maximum bonus for reducing the perceived size of a method during inlining. + + +# Reductions only come from optimization of dynamic type checks; all virtual methods on arrays are defined on Object. +V INLINE_PRECISE_REG_ARRAY_ARG_BONUS double 0.05 +Bonus given to inlining methods that are passed a register of a known precise type. + + +V INLINE_DECLARED_AASTORED_ARRAY_ARG_BONUS double 0.02 +Bonus given when there's potential to optimize checkstore portion of aastore bytecode on parameter + + +# Reductions come from optimization of dynamic type checks and improved inlining of virtual/interface calls +V INLINE_PRECISE_REG_CLASS_ARG_BONUS double 0.15 +Bonus given to inlining methods that are passed a register of a known precise type. + + +V INLINE_EXTANT_REG_CLASS_ARG_BONUS double 0.05 +Bonus given to inlining methods that are passed a register that's known not to be null. + + +# 5% credit for being an int constant; mainly in the hopes of control flow simplifications +V INLINE_INT_CONST_ARG_BONUS double 0.05 +Bonus given to inlining methods that are passed an int constant argument + + +# 10% credit for being 'null' as this enables a number of simplifications +V INLINE_NULL_CONST_ARG_BONUS double 0.10 +Bonus given to inlining methods that are passed a null constant argument + + +# 10% credit for being a string/class/object constant: inlining, constant folding, and Pure method opportunities +V INLINE_OBJECT_CONST_ARG_BONUS double 0.10 +Bonus given to inlining methods that are passed an object constant argument + + V INLINE_AI_MAX_TARGET_SIZE int (20*org.jikesrvm.classloader.NormalMethod.CALL_COST-org.jikesrvm.classloader.NormalMethod.SIMPLE_OPERATION_COST) Adaptive inlining heuristic: Upper bound on callee size This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-08 00:12:32
|
Revision: 15228 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15228&view=rev Author: captain5050 Date: 2008-12-08 00:12:05 +0000 (Mon, 08 Dec 2008) Log Message: ----------- RVM-727: fix to allow opt compiler to handle address to long and back conversions on Intel. This is necessary in Harmony where the internal representation of pointers is handled by longs (and not by a nice Pointer abstraction like Classpath). Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ConvertALUOperators.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java 2008-12-07 00:21:29 UTC (rev 15227) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/GenerateMagic.java 2008-12-08 00:12:05 UTC (rev 15228) @@ -768,13 +768,9 @@ bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, reg, bc2ir.popInt())); bc2ir.push(reg.copyD2U()); } else if (methodName == MagicNames.wordFromLong) { - if (VM.BuildFor64Addr) { - RegisterOperand reg = gc.temps.makeTemp(resultType); - bc2ir.appendInstruction(Unary.create(LONG_2ADDR, reg, bc2ir.popLong())); - bc2ir.push(reg.copyD2U()); - } else { - VM._assert(false); //should not reach - } + RegisterOperand reg = gc.temps.makeTemp(resultType); + bc2ir.appendInstruction(Unary.create(LONG_2ADDR, reg, bc2ir.popLong())); + bc2ir.push(reg.copyD2U()); } else if (methodName == MagicNames.wordToInt) { RegisterOperand reg = gc.temps.makeTempInt(); bc2ir.appendInstruction(Unary.create(ADDR_2INT, reg, bc2ir.popAddress())); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ConvertALUOperators.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ConvertALUOperators.java 2008-12-07 00:21:29 UTC (rev 15227) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/ConvertALUOperators.java 2008-12-08 00:12:05 UTC (rev 15228) @@ -289,8 +289,8 @@ case ADDR_2INT_opcode: s.operator = INT_MOVE; break; - case ADDR_2LONG_opcode: - s.operator = INT_2LONG; + case LONG_2ADDR_opcode: + s.operator = LONG_2INT; break; } Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-12-07 00:21:29 UTC (rev 15227) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32.rules 2008-12-08 00:12:05 UTC (rev 15228) @@ -1579,6 +1579,19 @@ EMIT(CPOS(P(p), MIR_Move.create(IA32_MOV, new RegisterOperand(lr, TypeReference.Int), IC(0)))); ##### +# ADDR_2LONG +##### +r: ADDR_2LONG(r) +33 +EMIT_INSTRUCTION +INT_2LONG(P(p), Unary.getResult(P(p)), Unary.getVal(P(p)), false); + +r: ADDR_2LONG(load32) +38 +EMIT_INSTRUCTION +INT_2LONG(P(p), Unary.getResult(P(p)), consumeMO(), false); + +##### # LONG_2INT ##### r: LONG_2INT(r) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-08 15:27:39
|
Revision: 15229 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15229&view=rev Author: captain5050 Date: 2008-12-08 15:27:36 +0000 (Mon, 08 Dec 2008) Log Message: ----------- RVM-725 WIP: introduce a factor that can be used to scale the weighting as we inline deeper and deeper methods. Organize default inline oracle slightly better and ensure that pragma inline methods can override method size concerns even at O0. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java 2008-12-08 00:12:05 UTC (rev 15228) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/DefaultInlineOracle.java 2008-12-08 15:27:36 UTC (rev 15229) @@ -58,12 +58,7 @@ if (verbose) VM.sysWriteln("Begin inline decision for " + "<" + caller + "," + bcIndex + "," + staticCallee + ">"); - // Stage 1: At all optimization levels we should attempt to inline - // trivial methods. Even if the inline code is never executed, - // inlining a trivial method is a no cost operation as the impact - // on code size should be negligible and compile time usually is - // reduced since we expect to eliminate the call instruction (or - // at worse replace one call instruction with another one). + // Stage 1: We definitely don't inline certain methods if (!state.isInvokeInterface()) { if (staticCallee.isNative()) { if (verbose) VM.sysWriteln("\tNO: native method\n"); @@ -73,28 +68,47 @@ if (verbose) VM.sysWriteln("\tNO: pragmaNoInline\n"); return InlineDecision.NO("pragmaNoInline"); } - if (// are we calling the throwable constructor + // We need throwable constructors to have their own compiled method IDs + // to correctly elide stack frames when generating stack traces (see + // StackTrace). + if (// are we calling the throwable constructor? staticCallee.isObjectInitializer() && (staticCallee.getDeclaringClass().getClassForType() == Throwable.class) && // and not from a throwable constructor !(caller.isObjectInitializer() && (caller.getDeclaringClass().getClassForType() == Throwable.class))) { - // We need throwable constructors to have their own compiled method IDs - // to correctly elide stack frames when generating stack traces (see - // StackTrace). if (verbose) VM.sysWriteln("\tNO: throwable constructor\n"); return InlineDecision.NO("throwable constructor"); } - - if (!staticCallee.isAbstract()) { + } + // Stage 2: At all optimization levels we should attempt to inline + // trivial methods. Even if the inline code is never executed, + // inlining a trivial method is a no cost operation as the impact + // on code size should be negligible and compile time usually is + // reduced since we expect to eliminate the call instruction (or + // at worse replace one call instruction with another one). + if (!state.isInvokeInterface() && !staticCallee.isAbstract()) { + // NB when the destination is known we will have refined the target so the + // above test passes + if (state.getHasPreciseTarget() || !needsGuard(staticCallee)) { + // call is guardless int inlinedSizeEstimate = inlinedSizeEstimate((NormalMethod) staticCallee, state); - boolean guardless = state.getHasPreciseTarget() || !needsGuard(staticCallee); - if (inlinedSizeEstimate < opts.INLINE_MAX_ALWAYS_INLINE_TARGET_SIZE && - guardless && - !state.getSequence().containsMethod(staticCallee)) { - if (verbose) VM.sysWriteln("\tYES: trivial guardless inline\n"); - return InlineDecision.YES(staticCallee, "trivial inline"); + if (inlinedSizeEstimate < opts.INLINE_MAX_ALWAYS_INLINE_TARGET_SIZE) { + // inlining is desirable + if (!state.getSequence().containsMethod(staticCallee)) { + // not recursive + if (verbose) VM.sysWriteln("\tYES: trivial guardless inline\n"); + return InlineDecision.YES(staticCallee, "trivial inline"); + } } + if (hasInlinePragma(staticCallee, state)) { + // inlining is desirable + if (!state.getSequence().containsMethod(staticCallee)) { + // not recursive + if (verbose) VM.sysWriteln("\tYES: pragma inline\n"); + return InlineDecision.YES(staticCallee, "pragma inline"); + } + } } } @@ -111,9 +125,8 @@ return InlineDecision.NO("Root method is massive; no non-trivial inlines"); } - // Stage 2: Determine based on profile data and static information + // Stage 3: Determine based on profile data and static information // what are the possible targets of this call. - // WeightedCallTargets targets = null; boolean purelyStatic = true; if (Controller.dcg != null && Controller.options.ADAPTIVE_INLINING) { @@ -192,7 +205,7 @@ // If there is a precise target, then targets contains exactly that target method. if (targets == null) return InlineDecision.NO("No potential targets identified"); - // Stage 3: We have one or more targets. Determine what if anything should be done with them. + // Stage 4: We have one or more targets. Determine what if anything should be done with them. final ArrayList<RVMMethod> methodsToInline = new ArrayList<RVMMethod>(); final ArrayList<Boolean> methodsNeedGuard = new ArrayList<Boolean>(); final double callSiteWeight = targets.totalWeight(); @@ -340,7 +353,7 @@ } }); - // Stage 4: Choose guards and package up the results in an InlineDecision object + // Stage 5: Choose guards and package up the results in an InlineDecision object if (methodsToInline.isEmpty()) { InlineDecision d = InlineDecision.NO("No desirable targets"); if (verbose) VM.sysWriteln("\tDecide: " + d); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java 2008-12-08 00:12:05 UTC (rev 15228) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/InlineTools.java 2008-12-08 15:27:36 UTC (rev 15229) @@ -153,7 +153,12 @@ } } reductionFactor = Math.max(reductionFactor, 1.0-opts.INLINE_MAX_ARG_BONUS); - return (int) (sizeEstimate * reductionFactor); + if (opts.INLINE_CALL_DEPTH_COST != 0.00) { + double depthCost = Math.pow(1.0+opts.INLINE_CALL_DEPTH_COST, (double)(state.getInlineDepth()+1)); + return (int) (sizeEstimate * reductionFactor * depthCost); + } else { + return (int) (sizeEstimate * reductionFactor); + } } /** Modified: rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-08 00:12:05 UTC (rev 15228) +++ rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-08 15:27:36 UTC (rev 15229) @@ -121,6 +121,10 @@ Bonus given to inlining methods that are passed an object constant argument +V INLINE_CALL_DEPTH_COST double 0.00 +As we inline deeper nested methods what cost (or bonus) do we wish to give to deter (or encourage) nesting of deeper methods? + + V INLINE_AI_MAX_TARGET_SIZE int (20*org.jikesrvm.classloader.NormalMethod.CALL_COST-org.jikesrvm.classloader.NormalMethod.SIMPLE_OPERATION_COST) Adaptive inlining heuristic: Upper bound on callee size This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-09 01:51:43
|
Revision: 15231 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15231&view=rev Author: captain5050 Date: 2008-12-09 01:51:39 +0000 (Tue, 09 Dec 2008) Log Message: ----------- RVM-725 WIP: create more opt options. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalConstantProp.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCopyProp.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ShortArrayReplacer.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/SplitBasicBlock.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/BlockCountSpillCost.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/SimpleSpillCost.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalConstantProp.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalConstantProp.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalConstantProp.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -100,7 +100,7 @@ } } if (didSomething) { - Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, s); + Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, ir.options, s); } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCopyProp.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCopyProp.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCopyProp.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -101,7 +101,7 @@ } } if (didSomething) { - Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, s); + Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, ir.options, s); } } // KILL Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -550,7 +550,7 @@ void foldConstants(IR ir) { boolean recomputeRegList = false; for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) { - Simplifier.DefUseEffect code = Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, s); + Simplifier.DefUseEffect code = Simplifier.simplify(ir.IRStage == IR.HIR, ir.regpool, ir.options, s); // If something was reduced (as opposed to folded) then its uses may // be different. This happens so infrequently that it's cheaper to // handle it by recomputing the DU from Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -28,7 +28,6 @@ import org.jikesrvm.classloader.RVMType; import org.jikesrvm.classloader.TypeReference; import org.jikesrvm.compilers.opt.driver.OptConstants; -import org.jikesrvm.compilers.opt.hir2lir.ConvertToLowLevelIR; import org.jikesrvm.compilers.opt.inlining.InlineSequence; import org.jikesrvm.compilers.opt.ir.AbstractRegisterPool; import org.jikesrvm.compilers.opt.ir.Binary; @@ -178,7 +177,7 @@ * @param s the instruction to simplify * @return one of UNCHANGED, MOVE_FOLDED, MOVE_REDUCED, TRAP_REDUCED, REDUCED */ - public static DefUseEffect simplify(boolean hir, AbstractRegisterPool regpool, Instruction s) { + public static DefUseEffect simplify(boolean hir, AbstractRegisterPool regpool, OptOptions opts, Instruction s) { DefUseEffect result; char opcode = s.getOpcode(); switch (opcode) { @@ -546,7 +545,7 @@ result = getDoesImplementFromTib(s); break; case REF_LOAD_opcode: - result = refLoad(s); + result = refLoad(s, opts); break; default: result = DefUseEffect.UNCHANGED; @@ -3540,7 +3539,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refLoad(Instruction s) { + private static DefUseEffect refLoad(Instruction s, OptOptions opts) { if (CF_TIB) { Operand base = Load.getAddress(s); if (base.isTIBConstant()) { @@ -3566,7 +3565,7 @@ } else if (tibArray.slotContainsCode(intSlot)) { // Only generate code constants when we want to make // some virtual calls go via the JTOC - if (ConvertToLowLevelIR.CALL_VIA_JTOC) { + if (opts.H2L_CALL_VIA_JTOC) { RVMMethod method = tib.value.getTIBMethodAtSlot(intSlot); result = new CodeConstantOperand(method); } else { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -2666,7 +2666,7 @@ private Instruction _unaryHelper(Operator operator, Operand val, TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = Unary.create(operator, t, val); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); push(Move.getClearVal(s)); @@ -2680,7 +2680,7 @@ private Instruction _unaryDualHelper(Operator operator, Operand val, TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = Unary.create(operator, t, val); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); pushDual(Move.getClearVal(s)); @@ -2695,7 +2695,7 @@ TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = Binary.create(operator, t, op1, op2); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); push(Move.getClearVal(s)); @@ -2710,7 +2710,7 @@ Operand guard, TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = GuardedBinary.create(operator, t, op1, op2, guard); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); push(Move.getClearVal(s)); @@ -2725,7 +2725,7 @@ TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = Binary.create(operator, t, op1, op2); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); pushDual(Move.getClearVal(s)); @@ -2740,7 +2740,7 @@ Operand guard, TypeReference type) { RegisterOperand t = gc.temps.makeTemp(type); Instruction s = GuardedBinary.create(operator, t, op1, op2, guard); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); pushDual(Move.getClearVal(s)); @@ -2822,7 +2822,7 @@ } else { RegisterOperand t = gc.temps.makeTemp(rtype); Call.setResult(s, t); - Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, s); + Simplifier.DefUseEffect simp = Simplifier.simplify(true, gc.temps, gc.options, s); if ((simp == Simplifier.DefUseEffect.MOVE_FOLDED) || (simp == Simplifier.DefUseEffect.MOVE_REDUCED)) { gc.temps.release(t); push(Move.getClearVal(s), rtype); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/StaticSplitting.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -49,7 +49,6 @@ public class StaticSplitting extends CompilerPhase { private static final boolean DEBUG = false; - private static final int MAX_COST = 10; // upper bound on instructions duplicated private final BranchOptimizations branchOpts; public StaticSplitting() { @@ -130,7 +129,7 @@ if (candTest == null) continue; BasicBlock coldPrev = findColdPrev(cand); if (coldPrev == null) continue; - if (tooBig(cand)) continue; + if (tooBig(cand, ir.options.CONTROL_STATIC_SPLITTING_MAX_COST)) continue; BasicBlock coldSucc = findColdSucc(cand, candTest); if (containsOSRPoint(coldSucc)) continue; if (DEBUG) { @@ -218,7 +217,7 @@ * static hints, we are only willing to * copy a very small amount of code. */ - private boolean tooBig(BasicBlock bb) { + private boolean tooBig(BasicBlock bb, int maxCost) { int cost = 0; for (InstructionEnumeration e = bb.forwardRealInstrEnumerator(); e.hasMoreElements();) { Instruction s = e.next(); @@ -229,7 +228,7 @@ } else { cost++; } - if (cost > MAX_COST) return true; + if (cost > maxCost) return true; } return false; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ShortArrayReplacer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ShortArrayReplacer.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/ShortArrayReplacer.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -118,12 +118,6 @@ } /** - * Arrays shorter than this length are candidates to be replaced by - * scalar values. - */ - public static final int SHORT_ARRAY_SIZE = 5; - - /** * Return an object representing this transformation for a given * allocation site * @@ -140,7 +134,7 @@ return null; } int s = size.asIntConstant().value; - if (s > SHORT_ARRAY_SIZE) { + if (s > ir.options.ESCAPE_MAX_ARRAY_SIZE) { return null; } if (s < 0) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -161,11 +161,6 @@ * we'll leave array loads in the LIR. */ public static final boolean LOWER_ARRAY_ACCESS = VM.BuildForPowerPC; - /** - * Plant virtual calls via the JTOC rather than from the tib of an - * object when possible - */ - public static final boolean CALL_VIA_JTOC = false; /** * Converts the given HIR to LIR. @@ -822,7 +817,7 @@ Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, Call.getClearAddress(v))); } else if (methOp.isVirtual()) { if (VM.VerifyAssertions) VM._assert(Call.hasAddress(v)); - if (CALL_VIA_JTOC && methOp.hasPreciseTarget()) { + if (ir.options.H2L_CALL_VIA_JTOC && methOp.hasPreciseTarget()) { // Call to precise type can go via JTOC RVMMethod target = methOp.getTarget(); Call.setAddress(v, @@ -849,7 +844,7 @@ // target == null => we are calling an unresolved <init> method. Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, Call.getClearAddress(v))); } else { - if (CALL_VIA_JTOC) { + if (ir.options.H2L_CALL_VIA_JTOC) { Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/SplitBasicBlock.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/SplitBasicBlock.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/SplitBasicBlock.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -19,12 +19,11 @@ import org.jikesrvm.compilers.opt.ir.Instruction; /** - * Splits a large basic block into smaller ones with size <= MAX_NUM_INSTRUCTIONS. + * Splits a large basic block into smaller ones with size <= + * OptOptions.L2M_MAX_BLOCK_SIZE */ public final class SplitBasicBlock extends CompilerPhase { - private static final int MAX_NUM_INSTRUCTIONS = 300; - public String getName() { return "SplitBasicBlock"; } public CompilerPhase newExecution(IR ir) { return this; } @@ -41,24 +40,20 @@ } } - // Splits bb. - // Returns null if no splitting is done. - // returns the second block if splitting is done. + /** + * Splits basic block + * + * @return null if no splitting is done, returns the second block if splitting is done. + */ BasicBlock splitEachBlock(BasicBlock bb, IR ir) { - int instCount = MAX_NUM_INSTRUCTIONS; + int instCount = ir.options.L2M_MAX_BLOCK_SIZE; for (Instruction inst = bb.firstInstruction(); inst != bb.lastInstruction(); inst = inst.nextInstructionInCodeOrder()) { - if ((--instCount) == 0) { + if ((--instCount) <= 0) { if (inst.isBranch()) { return null; // no need to split because all the rests are just branches } - if (inst.isMove()) { // why do we need this?? --dave - Instruction next = inst.nextInstructionInCodeOrder(); - if (next != bb.lastInstruction() && next.isImplicitLoad()) { - inst = next; - } - } // Now, split! return bb.splitNodeWithLinksAt(inst, ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/BlockCountSpillCost.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/BlockCountSpillCost.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/BlockCountSpillCost.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -37,6 +37,8 @@ * Calculate the estimated cost for each register. */ void calculate(IR ir) { + final double moveFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MOVE_FACTOR; + final double memoryOperandFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MEMORY_OPERAND_FACTOR; for (Enumeration<BasicBlock> blocks = ir.getBasicBlocks(); blocks.hasMoreElements();) { BasicBlock bb = blocks.nextElement(); float freq = bb.getExecutionFrequency(); @@ -44,10 +46,10 @@ Instruction s = e.nextElement(); double factor = freq; - if (s.isMove()) factor *= SimpleSpillCost.MOVE_FACTOR; + if (s.isMove()) factor *= moveFactor; double baseFactor = factor; if (SimpleSpillCost.hasBadSizeMemoryOperand(s)) { - baseFactor *= SimpleSpillCost.MEMORY_OPERAND_FACTOR; + baseFactor *= memoryOperandFactor; } // first deal with non-memory operands @@ -61,7 +63,7 @@ } } // now handle memory operands - factor *= SimpleSpillCost.MEMORY_OPERAND_FACTOR; + factor *= memoryOperandFactor; for (OperandEnumeration e2 = s.getMemoryOperands(); e2.hasMoreElements();) { MemoryOperand M = (MemoryOperand) e2.nextElement(); if (M.base != null) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/LinearScan.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -82,16 +82,6 @@ private static final boolean MUTATE_FMOV = VM.BuildForIA32; /** - * Attempt to coalesce to eliminate register moves? - */ - static final boolean COALESCE_MOVES = true; - - /** - * Attempt to coalesce stack locations? - */ - private static final boolean COALESCE_SPILLS = true; - - /** * debug flags */ private static final boolean DEBUG = false; @@ -1266,7 +1256,7 @@ RegisterRestrictions restrict = ir.stackManager.getRestrictions(); // first attempt to allocate to the preferred register - if (COALESCE_MOVES) { + if (ir.options.REGALLOC_COALESCE_MOVES) { Register p = getPhysicalPreference(ci); if (p != null) { if (DEBUG_COALESCE) { @@ -1311,7 +1301,7 @@ RegisterRestrictions restrict = ir.stackManager.getRestrictions(); // first attempt to allocate to the preferred register - if (COALESCE_MOVES) { + if (ir.options.REGALLOC_COALESCE_MOVES) { Register p = getPhysicalPreference(symb); if (p != null) { if (DEBUG_COALESCE) { @@ -1957,7 +1947,7 @@ // Search the free intervals and try to find an interval to // reuse. First look for the preferred interval. - if (COALESCE_SPILLS) { + if (ir.options.REGALLOC_COALESCE_SPILLS) { result = getSpillPreference(ci, spillSize); if (result != null) { if (DEBUG_COALESCE) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/SimpleSpillCost.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/SimpleSpillCost.java 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/SimpleSpillCost.java 2008-12-09 01:51:39 UTC (rev 15231) @@ -26,17 +26,6 @@ */ class SimpleSpillCost extends SpillCostEstimator { - // modify the following factor to adjust the spill penalty in move - // instructions - public static final double MOVE_FACTOR = 1.0; - - // registers used in memory operands may hurt more than 'normal', since - // they will definitely use a scratch register. - // rationale for 5: 5 instructions affected when using a scratch register. - // (2 to save physical register, 1 to load scratch, 1 to dump scratch, and - // the original) - public static final double MEMORY_OPERAND_FACTOR = 5.0; - SimpleSpillCost(IR ir) { calculate(ir); } @@ -45,17 +34,19 @@ * Calculate the estimated cost for each register. */ void calculate(IR ir) { + final double moveFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MOVE_FACTOR; + final double memoryOperandFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MEMORY_OPERAND_FACTOR; for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements();) { BasicBlock bb = e.nextElement(); for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements();) { Instruction s = ie.nextElement(); double factor = (bb.getInfrequent()) ? 0.0 : 1.0; if (s.isMove()) { - factor *= MOVE_FACTOR; + factor *= moveFactor; } double baseFactor = factor; if (hasBadSizeMemoryOperand(s)) { - baseFactor *= MEMORY_OPERAND_FACTOR; + baseFactor *= memoryOperandFactor; } // first deal with non-memory operands for (Enumeration<Operand> e2 = s.getRootOperands(); e2.hasMoreElements();) { @@ -68,7 +59,7 @@ } } // now handle memory operands - factor *= MEMORY_OPERAND_FACTOR; + factor *= memoryOperandFactor; for (Enumeration<Operand> e2 = s.getMemoryOperands(); e2.hasMoreElements();) { MemoryOperand M = (MemoryOperand) e2.nextElement(); if (M.base != null) { Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-09 01:51:39 UTC (rev 15231) @@ -142,6 +142,9 @@ H2L_NO_CALLEE_EXCEPTIONS -1 false Assert that any callee of this compiled method will not throw exceptions. Cannot be properly set on command line. +H2L_CALL_VIA_JTOC -1 false +Plant virtual calls via the JTOC rather than from the tib of anobject when possible + ########## # Options during conversion from LIR to MIR ########## @@ -152,6 +155,15 @@ Perform prepass instruction scheduling ########## +# Options during register allocation +########## +REGALLOC_COALESCE_MOVES 0 true +Attempt to coalesce to eliminate register moves? + +REGALLOC_COALESCE_SPILLS 0 true +Attempt to coalesce stack locations? + +########## # Options for adaptive compilation ########## ADAPTIVE_INSTRUMENTATION_SAMPLING -1 false Modified: rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-09 01:49:38 UTC (rev 15230) +++ rvmroot/trunk/rvm/src-generated/options/ValueOptions.opt.dat 2008-12-09 01:51:39 UTC (rev 15231) @@ -45,16 +45,36 @@ Threshold at which a conditional branch is considered to be skewed +V ESCAPE_MAX_ARRAY_SIZE int 5 +Maximum size of array to replaced with registers by simple escape analysis + + V SSA_LOAD_ELIMINATION_ROUNDS int 3 How many rounds of redundant load elimination will we attempt? +V L2M_MAX_BLOCK_SIZE int 300 +Maximum size of block for BURS, larger blocks are split + + E REGALLOC_SPILL_COST_ESTIMATE byte REGALLOC_BLOCK_COUNT_SPILL_COST Selection of spilling heuristic "REGALLOC_SIMPLE_SPILL_COST simpleSpillCost simple" \ "REGALLOC_BRAINDEAD_SPILL_COST brainDeadSpillCost brainDead" \ "REGALLOC_BLOCK_COUNT_SPILL_COST blockCountSpillCost blockCount" +V REGALLOC_SIMPLE_SPILL_COST_MOVE_FACTOR double 1.0 +spill penalty for move instructions + + +# registers used in memory operands may hurt more than 'normal', since they +# will definitely use a scratch register. rationale for 5: 5 instructions +# affected when using a scratch register. (2 to save physical register, 1 to +# load scratch, 1 to dump scratch, and the original) +V REGALLOC_SIMPLE_SPILL_COST_MEMORY_OPERAND_FACTOR double 5.0 +spill penalty for registers used in memory operands + + V CONTROL_TABLESWITCH_CUTOFF int 8 If a tableswitch comprises this many or fewer comparisons convert it into multiple if-then-else style branches @@ -67,6 +87,10 @@ Unroll loops. Duplicates the loop body 2^n times. +V CONTROL_STATIC_SPLITTING_MAX_COST int 10 +Upper bound on the number of instructions duplicated per block when trying to create hot traces with static splitting + + V INLINE_MAX_TARGET_SIZE int (4*org.jikesrvm.classloader.NormalMethod.CALL_COST-org.jikesrvm.classloader.NormalMethod.SIMPLE_OPERATION_COST) Static inlining heuristic: Upper bound on callee size This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-20 23:00:06
|
Revision: 15234 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15234&view=rev Author: captain5050 Date: 2008-12-20 23:00:01 +0000 (Sat, 20 Dec 2008) Log Message: ----------- RVM-725 WIP: make simplifier operations configurable via options. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-12-20 22:57:43 UTC (rev 15233) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-12-20 23:00:01 UTC (rev 15234) @@ -94,45 +94,7 @@ * 500 lines of clever code. */ public abstract class Simplifier extends IRTools { - // NOTE: The convention is that constant folding is controlled based - // on the type of the result of the operator, not the type of its inputs. /** - * Constant fold integer operations? - */ - public static final boolean CF_INT = true; - /** - * Constant fold address operations? - */ - public static final boolean CF_LONG = true; - - /** - * Constant fold address operations? - */ - public static final boolean CF_ADDR = true; - - /** - * Constant fold float operations? Default is true, flip to avoid - * consuming precious JTOC slots to hold new constant values. - */ - public static final boolean CF_FLOAT = true; - /** - * Constant fold double operations? Default is true, flip to avoid - * consuming precious JTOC slots to hold new constant values. - */ - public static final boolean CF_DOUBLE = true; - /** - * Constant fold field operations? Default is true, flip to avoid - * consuming precious JTOC slots to hold new constant values. - */ - public static final boolean CF_FIELDS = true; - - /** - * Constant fold TIB operations? Default is true, flip to avoid - * consuming precious JTOC slots to hold new constant values. - */ - public static final boolean CF_TIB = true; - - /** * Effect of the simplification on Def-Use chains */ public enum DefUseEffect { @@ -174,6 +136,7 @@ * * @param hir is this the HIR phase? * @param regpool register pool in case simplification requires a temporary register + * @param opts options for this compilation * @param s the instruction to simplify * @return one of UNCHANGED, MOVE_FOLDED, MOVE_REDUCED, TRAP_REDUCED, REDUCED */ @@ -185,364 +148,364 @@ // GUARD operations //////////////////// case GUARD_COMBINE_opcode: - result = guardCombine(s); + result = guardCombine(s, opts); break; //////////////////// // TRAP operations //////////////////// case TRAP_IF_opcode: - result = trapIf(s); + result = trapIf(s, opts); break; case NULL_CHECK_opcode: - result = nullCheck(s); + result = nullCheck(s, opts); break; case INT_ZERO_CHECK_opcode: - result = intZeroCheck(s); + result = intZeroCheck(s, opts); break; case LONG_ZERO_CHECK_opcode: - result = longZeroCheck(s); + result = longZeroCheck(s, opts); break; case CHECKCAST_opcode: - result = checkcast(s); + result = checkcast(s, opts); break; case CHECKCAST_UNRESOLVED_opcode: - result = checkcast(s); + result = checkcast(s, opts); break; case CHECKCAST_NOTNULL_opcode: - result = checkcastNotNull(s); + result = checkcastNotNull(s, opts); break; case INSTANCEOF_opcode: - result = instanceOf(s); + result = instanceOf(s, opts); break; case INSTANCEOF_NOTNULL_opcode: - result = instanceOfNotNull(s); + result = instanceOfNotNull(s, opts); break; case OBJARRAY_STORE_CHECK_opcode: - result = objarrayStoreCheck(s); + result = objarrayStoreCheck(s, opts); break; case OBJARRAY_STORE_CHECK_NOTNULL_opcode: - result = objarrayStoreCheckNotNull(s); + result = objarrayStoreCheckNotNull(s, opts); break; case MUST_IMPLEMENT_INTERFACE_opcode: - result = mustImplementInterface(s); + result = mustImplementInterface(s, opts); break; //////////////////// // Conditional moves //////////////////// case INT_COND_MOVE_opcode: - result = intCondMove(s); + result = intCondMove(s, opts); break; case LONG_COND_MOVE_opcode: - result = longCondMove(s); + result = longCondMove(s, opts); break; case FLOAT_COND_MOVE_opcode: - result = floatCondMove(s); + result = floatCondMove(s, opts); break; case DOUBLE_COND_MOVE_opcode: - result = doubleCondMove(s); + result = doubleCondMove(s, opts); break; case REF_COND_MOVE_opcode: - result = refCondMove(s); + result = refCondMove(s, opts); break; case GUARD_COND_MOVE_opcode: - result = guardCondMove(s); + result = guardCondMove(s, opts); break; //////////////////// // INT ALU operations //////////////////// case BOOLEAN_NOT_opcode: - result = booleanNot(s); + result = booleanNot(s, opts); break; case BOOLEAN_CMP_INT_opcode: - result = booleanCmpInt(s); + result = booleanCmpInt(s, opts); break; case BOOLEAN_CMP_ADDR_opcode: - result = booleanCmpAddr(s); + result = booleanCmpAddr(s, opts); break; case INT_ADD_opcode: - result = intAdd(s); + result = intAdd(s, opts); break; case INT_AND_opcode: - result = intAnd(s); + result = intAnd(s, opts); break; case INT_DIV_opcode: - result = intDiv(regpool, s); + result = intDiv(regpool, s, opts); break; case INT_MUL_opcode: - result = intMul(regpool, s); + result = intMul(regpool, s, opts); break; case INT_NEG_opcode: - result = intNeg(s); + result = intNeg(s, opts); break; case INT_NOT_opcode: - result = intNot(s); + result = intNot(s, opts); break; case INT_OR_opcode: - result = intOr(s); + result = intOr(s, opts); break; case INT_REM_opcode: - result = intRem(s); + result = intRem(s, opts); break; case INT_SHL_opcode: - result = intShl(s); + result = intShl(s, opts); break; case INT_SHR_opcode: - result = intShr(s); + result = intShr(s, opts); break; case INT_SUB_opcode: - result = intSub(s); + result = intSub(s, opts); break; case INT_USHR_opcode: - result = intUshr(s); + result = intUshr(s, opts); break; case INT_XOR_opcode: - result = intXor(s); + result = intXor(s, opts); break; //////////////////// // WORD ALU operations //////////////////// case REF_ADD_opcode: - result = refAdd(s); + result = refAdd(s, opts); break; case REF_AND_opcode: - result = refAnd(s); + result = refAnd(s, opts); break; case REF_SHL_opcode: - result = refShl(s); + result = refShl(s, opts); break; case REF_SHR_opcode: - result = refShr(s); + result = refShr(s, opts); break; case REF_NEG_opcode: - result = refNeg(s); + result = refNeg(s, opts); break; case REF_NOT_opcode: - result = refNot(s); + result = refNot(s, opts); break; case REF_OR_opcode: - result = refOr(s); + result = refOr(s, opts); break; case REF_SUB_opcode: - result = refSub(s); + result = refSub(s, opts); break; case REF_USHR_opcode: - result = refUshr(s); + result = refUshr(s, opts); break; case REF_XOR_opcode: - result = refXor(s); + result = refXor(s, opts); break; //////////////////// // LONG ALU operations //////////////////// case LONG_ADD_opcode: - result = longAdd(s); + result = longAdd(s, opts); break; case LONG_AND_opcode: - result = longAnd(s); + result = longAnd(s, opts); break; case LONG_CMP_opcode: - result = longCmp(s); + result = longCmp(s, opts); break; case LONG_DIV_opcode: - result = longDiv(s); + result = longDiv(s, opts); break; case LONG_MUL_opcode: - result = longMul(regpool, s); + result = longMul(regpool, s, opts); break; case LONG_NEG_opcode: - result = longNeg(s); + result = longNeg(s, opts); break; case LONG_NOT_opcode: - result = longNot(s); + result = longNot(s, opts); break; case LONG_OR_opcode: - result = longOr(s); + result = longOr(s, opts); break; case LONG_REM_opcode: - result = longRem(s); + result = longRem(s, opts); break; case LONG_SHL_opcode: - result = longShl(s); + result = longShl(s, opts); break; case LONG_SHR_opcode: - result = longShr(s); + result = longShr(s, opts); break; case LONG_SUB_opcode: - result = longSub(s); + result = longSub(s, opts); break; case LONG_USHR_opcode: - result = longUshr(s); + result = longUshr(s, opts); break; case LONG_XOR_opcode: - result = longXor(s); + result = longXor(s, opts); break; //////////////////// // FLOAT ALU operations //////////////////// case FLOAT_ADD_opcode: - result = floatAdd(s); + result = floatAdd(s, opts); break; case FLOAT_CMPG_opcode: - result = floatCmpg(s); + result = floatCmpg(s, opts); break; case FLOAT_CMPL_opcode: - result = floatCmpl(s); + result = floatCmpl(s, opts); break; case FLOAT_DIV_opcode: - result = floatDiv(s); + result = floatDiv(s, opts); break; case FLOAT_MUL_opcode: - result = floatMul(s); + result = floatMul(s, opts); break; case FLOAT_NEG_opcode: - result = floatNeg(s); + result = floatNeg(s, opts); break; case FLOAT_REM_opcode: - result = floatRem(s); + result = floatRem(s, opts); break; case FLOAT_SUB_opcode: - result = floatSub(s); + result = floatSub(s, opts); break; case FLOAT_SQRT_opcode: - result = floatSqrt(s); + result = floatSqrt(s, opts); break; //////////////////// // DOUBLE ALU operations //////////////////// case DOUBLE_ADD_opcode: - result = doubleAdd(s); + result = doubleAdd(s, opts); break; case DOUBLE_CMPG_opcode: - result = doubleCmpg(s); + result = doubleCmpg(s, opts); break; case DOUBLE_CMPL_opcode: - result = doubleCmpl(s); + result = doubleCmpl(s, opts); break; case DOUBLE_DIV_opcode: - result = doubleDiv(s); + result = doubleDiv(s, opts); break; case DOUBLE_MUL_opcode: - result = doubleMul(s); + result = doubleMul(s, opts); break; case DOUBLE_NEG_opcode: - result = doubleNeg(s); + result = doubleNeg(s, opts); break; case DOUBLE_REM_opcode: - result = doubleRem(s); + result = doubleRem(s, opts); break; case DOUBLE_SUB_opcode: - result = doubleSub(s); + result = doubleSub(s, opts); break; case DOUBLE_SQRT_opcode: - result = doubleSqrt(s); + result = doubleSqrt(s, opts); break; //////////////////// // CONVERSION operations //////////////////// case DOUBLE_2FLOAT_opcode: - result = double2Float(s); + result = double2Float(s, opts); break; case DOUBLE_2INT_opcode: - result = double2Int(s); + result = double2Int(s, opts); break; case DOUBLE_2LONG_opcode: - result = double2Long(s); + result = double2Long(s, opts); break; case DOUBLE_AS_LONG_BITS_opcode: - result = doubleAsLongBits(s); + result = doubleAsLongBits(s, opts); break; case INT_2DOUBLE_opcode: - result = int2Double(s); + result = int2Double(s, opts); break; case INT_2BYTE_opcode: - result = int2Byte(s); + result = int2Byte(s, opts); break; case INT_2USHORT_opcode: - result = int2UShort(s); + result = int2UShort(s, opts); break; case INT_2FLOAT_opcode: - result = int2Float(s); + result = int2Float(s, opts); break; case INT_2LONG_opcode: - result = int2Long(s); + result = int2Long(s, opts); break; case INT_2ADDRSigExt_opcode: - result = int2AddrSigExt(s); + result = int2AddrSigExt(s, opts); break; case INT_2ADDRZerExt_opcode: - result = int2AddrZerExt(s); + result = int2AddrZerExt(s, opts); break; case LONG_2ADDR_opcode: - result = long2Addr(s); + result = long2Addr(s, opts); break; case INT_2SHORT_opcode: - result = int2Short(s); + result = int2Short(s, opts); break; case INT_BITS_AS_FLOAT_opcode: - result = intBitsAsFloat(s); + result = intBitsAsFloat(s, opts); break; case ADDR_2INT_opcode: - result = addr2Int(s); + result = addr2Int(s, opts); break; case ADDR_2LONG_opcode: - result = addr2Long(s); + result = addr2Long(s, opts); break; case FLOAT_2DOUBLE_opcode: - result = float2Double(s); + result = float2Double(s, opts); break; case FLOAT_2INT_opcode: - result = float2Int(s); + result = float2Int(s, opts); break; case FLOAT_2LONG_opcode: - result = float2Long(s); + result = float2Long(s, opts); break; case FLOAT_AS_INT_BITS_opcode: - result = floatAsIntBits(s); + result = floatAsIntBits(s, opts); break; case LONG_2FLOAT_opcode: - result = long2Float(s); + result = long2Float(s, opts); break; case LONG_2INT_opcode: - result = long2Int(s); + result = long2Int(s, opts); break; case LONG_2DOUBLE_opcode: - result = long2Double(s); + result = long2Double(s, opts); break; case LONG_BITS_AS_DOUBLE_opcode: - result = longBitsAsDouble(s); + result = longBitsAsDouble(s, opts); break; //////////////////// // Field operations //////////////////// case ARRAYLENGTH_opcode: - result = arrayLength(s); + result = arrayLength(s, opts); break; case BOUNDS_CHECK_opcode: - result = boundsCheck(s); + result = boundsCheck(s, opts); break; case CALL_opcode: - result = call(hir, regpool, s); + result = call(hir, regpool, s, opts); break; case GETFIELD_opcode: - result = getField(s); + result = getField(s, opts); break; case GET_OBJ_TIB_opcode: - result = getObjTib(s); + result = getObjTib(s, opts); break; case GET_CLASS_TIB_opcode: - result = getClassTib(s); + result = getClassTib(s, opts); break; case GET_TYPE_FROM_TIB_opcode: - result = getTypeFromTib(s); + result = getTypeFromTib(s, opts); break; case GET_ARRAY_ELEMENT_TIB_FROM_TIB_opcode: - result = getArrayElementTibFromTib(s); + result = getArrayElementTibFromTib(s, opts); break; case GET_SUPERCLASS_IDS_FROM_TIB_opcode: - result = getSuperclassIdsFromTib(s); + result = getSuperclassIdsFromTib(s, opts); break; case GET_DOES_IMPLEMENT_FROM_TIB_opcode: - result = getDoesImplementFromTib(s); + result = getDoesImplementFromTib(s, opts); break; case REF_LOAD_opcode: result = refLoad(s, opts); @@ -575,7 +538,7 @@ return result; } - private static DefUseEffect guardCombine(Instruction s) { + private static DefUseEffect guardCombine(Instruction s, OptOptions opts) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op1.similar(op2) || (op2 instanceof TrueGuardOperand)) { @@ -596,7 +559,7 @@ } } - private static DefUseEffect trapIf(Instruction s) { + private static DefUseEffect trapIf(Instruction s, OptOptions opts) { { Operand op1 = TrapIf.getVal1(s); Operand op2 = TrapIf.getVal2(s); @@ -625,7 +588,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect nullCheck(Instruction s) { + private static DefUseEffect nullCheck(Instruction s, OptOptions opts) { Operand ref = NullCheck.getRef(s); if (ref.isNullConstant() || (ref.isAddressConstant() && ref.asAddressConstant().value.isZero())) { Trap.mutate(s, TRAP, NullCheck.getClearGuardResult(s), TrapCodeOperand.NullPtr()); @@ -643,7 +606,7 @@ } } - private static DefUseEffect intZeroCheck(Instruction s) { + private static DefUseEffect intZeroCheck(Instruction s, OptOptions opts) { { Operand op = ZeroCheck.getValue(s); if (op.isIntConstant()) { @@ -660,7 +623,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longZeroCheck(Instruction s) { + private static DefUseEffect longZeroCheck(Instruction s, OptOptions opts) { { Operand op = ZeroCheck.getValue(s); if (op.isLongConstant()) { @@ -676,7 +639,7 @@ } return DefUseEffect.UNCHANGED; } - private static DefUseEffect checkcast(Instruction s) { + private static DefUseEffect checkcast(Instruction s, OptOptions opts) { Operand ref = TypeCheck.getRef(s); if (ref.isNullConstant()) { Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref); @@ -686,7 +649,7 @@ return DefUseEffect.MOVE_REDUCED; } else if (ref.isConstant()) { s.operator = CHECKCAST_NOTNULL; - return checkcastNotNull(s); + return checkcastNotNull(s, opts); } else { TypeReference lhsType = TypeCheck.getType(s).getTypeRef(); TypeReference rhsType = ref.getType(); @@ -704,7 +667,7 @@ } } - private static DefUseEffect checkcastNotNull(Instruction s) { + private static DefUseEffect checkcastNotNull(Instruction s, OptOptions opts) { Operand ref = TypeCheck.getRef(s); TypeReference lhsType = TypeCheck.getType(s).getTypeRef(); TypeReference rhsType = ref.getType(); @@ -728,14 +691,14 @@ return DefUseEffect.UNCHANGED; } } - private static DefUseEffect instanceOf(Instruction s) { + private static DefUseEffect instanceOf(Instruction s, OptOptions opts) { Operand ref = InstanceOf.getRef(s); if (ref.isNullConstant()) { Move.mutate(s, INT_MOVE, InstanceOf.getClearResult(s), IC(0)); return DefUseEffect.MOVE_FOLDED; } else if (ref.isConstant()) { s.operator = INSTANCEOF_NOTNULL; - return instanceOfNotNull(s); + return instanceOfNotNull(s, opts); } else { TypeReference lhsType = InstanceOf.getType(s).getTypeRef(); TypeReference rhsType = ref.getType(); @@ -756,7 +719,7 @@ } } - private static DefUseEffect instanceOfNotNull(Instruction s) { + private static DefUseEffect instanceOfNotNull(Instruction s, OptOptions opts) { { Operand ref = InstanceOf.getRef(s); TypeReference lhsType = InstanceOf.getType(s).getTypeRef(); @@ -777,7 +740,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect objarrayStoreCheck(Instruction s) { + private static DefUseEffect objarrayStoreCheck(Instruction s, OptOptions opts) { Operand val = StoreCheck.getVal(s); if (val.isNullConstant()) { // Writing null into an array is trivially safe @@ -825,7 +788,7 @@ } } - private static DefUseEffect objarrayStoreCheckNotNull(Instruction s) { + private static DefUseEffect objarrayStoreCheckNotNull(Instruction s, OptOptions opts) { Operand val = StoreCheck.getVal(s); Operand ref = StoreCheck.getRef(s); TypeReference arrayTypeRef = ref.getType(); @@ -867,7 +830,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect mustImplementInterface(Instruction s) { + private static DefUseEffect mustImplementInterface(Instruction s, OptOptions opts) { Operand ref = TypeCheck.getRef(s); if (ref.isNullConstant()) { // Possible situation from constant propagation. This operation @@ -905,7 +868,7 @@ } } - private static DefUseEffect intCondMove(Instruction s) { + private static DefUseEffect intCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); Operand val2 = CondMove.getVal2(s); @@ -970,7 +933,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longCondMove(Instruction s) { + private static DefUseEffect longCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); Operand val2 = CondMove.getVal2(s); @@ -1033,7 +996,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatCondMove(Instruction s) { + private static DefUseEffect floatCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); Operand val2 = CondMove.getVal2(s); @@ -1062,7 +1025,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleCondMove(Instruction s) { + private static DefUseEffect doubleCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); Operand val2 = CondMove.getVal2(s); @@ -1091,7 +1054,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refCondMove(Instruction s) { + private static DefUseEffect refCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); if (val1.isConstant()) { @@ -1122,7 +1085,7 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect guardCondMove(Instruction s) { + private static DefUseEffect guardCondMove(Instruction s, OptOptions opts) { { Operand val1 = CondMove.getVal1(s); if (val1.isConstant()) { @@ -1153,8 +1116,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect booleanNot(Instruction s) { - if (CF_INT) { + private static DefUseEffect booleanNot(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -1170,8 +1133,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect booleanCmpInt(Instruction s) { - if (CF_INT) { + private static DefUseEffect booleanCmpInt(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op1 = BooleanCmp.getVal1(s); Operand op2 = BooleanCmp.getVal2(s); if (op1.isConstant()) { @@ -1209,8 +1172,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect booleanCmpAddr(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect booleanCmpAddr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op1 = BooleanCmp.getVal1(s); Operand op2 = BooleanCmp.getVal2(s); if (op1.isConstant()) { @@ -1233,8 +1196,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intAdd(Instruction s) { - if (CF_INT) { + private static DefUseEffect intAdd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isIntConstant()) { @@ -1265,8 +1228,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intAnd(Instruction s) { - if (CF_INT) { + private static DefUseEffect intAnd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -1298,8 +1261,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intDiv(AbstractRegisterPool regpool, Instruction s) { - if (CF_INT) { + private static DefUseEffect intDiv(AbstractRegisterPool regpool, Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op1 = GuardedBinary.getVal1(s); Operand op2 = GuardedBinary.getVal2(s); if (op1.similar(op2)) { @@ -1354,8 +1317,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intMul(AbstractRegisterPool regpool, Instruction s) { - if (CF_INT) { + private static DefUseEffect intMul(AbstractRegisterPool regpool, Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isIntConstant()) { @@ -1368,14 +1331,14 @@ return DefUseEffect.MOVE_FOLDED; } else { // ONLY OP2 IS CONSTANT - return multiplyByConstant(regpool, s, op1, op2); + return multiplyByConstant(regpool, s, op1, op2, opts); } } } return DefUseEffect.UNCHANGED; } - private static DefUseEffect multiplyByConstant(AbstractRegisterPool regpool, Instruction s, Operand op1, Operand op2) { + private static DefUseEffect multiplyByConstant(AbstractRegisterPool regpool, Instruction s, Operand op1, Operand op2, OptOptions opts) { Operator addOperator, moveOperator, negateOperator, shiftLeftOperator; ConstantOperand zero; long val2; @@ -1526,8 +1489,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intNeg(Instruction s) { - if (CF_INT) { + private static DefUseEffect intNeg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -1539,8 +1502,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intNot(Instruction s) { - if (CF_INT) { + private static DefUseEffect intNot(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -1552,8 +1515,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intOr(Instruction s) { - if (CF_INT) { + private static DefUseEffect intOr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -1585,8 +1548,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intRem(Instruction s) { - if (CF_INT) { + private static DefUseEffect intRem(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op1 = GuardedBinary.getVal1(s); Operand op2 = GuardedBinary.getVal2(s); if (op1.similar(op2)) { @@ -1621,8 +1584,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intShl(Instruction s) { - if (CF_INT) { + private static DefUseEffect intShl(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -1655,8 +1618,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intShr(Instruction s) { - if (CF_INT) { + private static DefUseEffect intShr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op2.isIntConstant()) { @@ -1689,8 +1652,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intSub(Instruction s) { - if (CF_INT) { + private static DefUseEffect intSub(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op1.similar(op2)) { @@ -1726,8 +1689,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intUshr(Instruction s) { - if (CF_INT) { + private static DefUseEffect intUshr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -1760,8 +1723,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intXor(Instruction s) { - if (CF_INT) { + private static DefUseEffect intXor(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -1794,8 +1757,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refAdd(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refAdd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isConstant() && !op2.isMovableObjectConstant()) { @@ -1831,8 +1794,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refAnd(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refAnd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -1864,8 +1827,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refShl(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refShl(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -1898,8 +1861,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refShr(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refShr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op2.isIntConstant()) { @@ -1933,8 +1896,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refNeg(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refNeg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op = Unary.getVal(s); if (op.isConstant() && !op.isMovableObjectConstant()) { // CONSTANT: FOLD @@ -1947,8 +1910,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refNot(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refNot(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op = Unary.getVal(s); if (op.isConstant() && !op.isMovableObjectConstant()) { // CONSTANT: FOLD @@ -1960,8 +1923,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refOr(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refOr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -1993,8 +1956,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refSub(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refSub(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op1.similar(op2)) { @@ -2040,8 +2003,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refUshr(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refUshr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -2074,8 +2037,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect refXor(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect refXor(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -2107,8 +2070,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longAdd(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longAdd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isLongConstant()) { @@ -2139,8 +2102,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longAnd(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longAnd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -2172,8 +2135,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longCmp(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longCmp(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op1.similar(op2)) { @@ -2195,8 +2158,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longDiv(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longDiv(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op1 = GuardedBinary.getVal1(s); Operand op2 = GuardedBinary.getVal2(s); if (op1.similar(op2)) { @@ -2230,8 +2193,8 @@ } return DefUseEffect.UNCHANGED; } - private static DefUseEffect longMul(AbstractRegisterPool regpool, Instruction s) { - if (CF_LONG) { + private static DefUseEffect longMul(AbstractRegisterPool regpool, Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isLongConstant()) { @@ -2244,15 +2207,15 @@ return DefUseEffect.MOVE_FOLDED; } else { // ONLY OP2 IS CONSTANT - return multiplyByConstant(regpool, s, op1, op2); + return multiplyByConstant(regpool, s, op1, op2, opts); } } } return DefUseEffect.UNCHANGED; } - private static DefUseEffect longNeg(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longNeg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -2264,8 +2227,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longNot(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longNot(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { long val = op.asLongConstant().value; @@ -2277,8 +2240,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longOr(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longOr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -2310,8 +2273,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longRem(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longRem(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op1 = GuardedBinary.getVal1(s); Operand op2 = GuardedBinary.getVal2(s); if (op1.similar(op2)) { @@ -2346,8 +2309,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longShl(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longShl(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -2380,8 +2343,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longShr(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longShr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op2.isIntConstant()) { @@ -2414,8 +2377,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longSub(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longSub(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op1.similar(op2)) { @@ -2452,8 +2415,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longUshr(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longUshr(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op2 = Binary.getVal2(s); Operand op1 = Binary.getVal1(s); if (op2.isIntConstant()) { @@ -2486,8 +2449,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longXor(Instruction s) { - if (CF_LONG) { + private static DefUseEffect longXor(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { canonicalizeCommutativeOperator(s); Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); @@ -2519,8 +2482,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatAdd(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatAdd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { @@ -2542,8 +2505,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatCmpg(Instruction s) { - if (CF_INT) { + private static DefUseEffect floatCmpg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { Operand op1 = Binary.getVal1(s); @@ -2560,8 +2523,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatCmpl(Instruction s) { - if (CF_INT) { + private static DefUseEffect floatCmpl(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { Operand op1 = Binary.getVal1(s); @@ -2578,8 +2541,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatDiv(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatDiv(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { Operand op1 = Binary.getVal1(s); @@ -2595,8 +2558,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatMul(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatMul(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { @@ -2618,8 +2581,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatNeg(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatNeg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -2631,8 +2594,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatRem(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatRem(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { Operand op1 = Binary.getVal1(s); @@ -2648,8 +2611,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatSub(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatSub(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op2.isFloatConstant()) { @@ -2673,8 +2636,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatSqrt(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect floatSqrt(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -2686,8 +2649,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleAdd(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleAdd(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { @@ -2709,8 +2672,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleCmpg(Instruction s) { - if (CF_INT) { + private static DefUseEffect doubleCmpg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { Operand op1 = Binary.getVal1(s); @@ -2727,8 +2690,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleCmpl(Instruction s) { - if (CF_INT) { + private static DefUseEffect doubleCmpl(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { Operand op1 = Binary.getVal1(s); @@ -2745,8 +2708,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleDiv(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleDiv(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { Operand op1 = Binary.getVal1(s); @@ -2762,8 +2725,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleMul(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleMul(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { canonicalizeCommutativeOperator(s); Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { @@ -2785,8 +2748,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleNeg(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleNeg(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2798,8 +2761,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleRem(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleRem(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { Operand op1 = Binary.getVal1(s); @@ -2815,8 +2778,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleSub(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleSub(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op1 = Binary.getVal1(s); Operand op2 = Binary.getVal2(s); if (op2.isDoubleConstant()) { @@ -2840,8 +2803,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleSqrt(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect doubleSqrt(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2853,8 +2816,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect double2Float(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect double2Float(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2866,8 +2829,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect double2Int(Instruction s) { - if (CF_INT) { + private static DefUseEffect double2Int(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2879,8 +2842,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect double2Long(Instruction s) { - if (CF_LONG) { + private static DefUseEffect double2Long(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2892,8 +2855,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect doubleAsLongBits(Instruction s) { - if (CF_LONG) { + private static DefUseEffect doubleAsLongBits(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isDoubleConstant()) { // CONSTANT: FOLD @@ -2905,8 +2868,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2Double(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect int2Double(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2918,8 +2881,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2Byte(Instruction s) { - if (CF_INT) { + private static DefUseEffect int2Byte(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2931,8 +2894,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2UShort(Instruction s) { - if (CF_INT) { + private static DefUseEffect int2UShort(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2944,8 +2907,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2Float(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect int2Float(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2957,8 +2920,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2Long(Instruction s) { - if (CF_LONG) { + private static DefUseEffect int2Long(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2970,8 +2933,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2AddrSigExt(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect int2AddrSigExt(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2983,8 +2946,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2AddrZerExt(Instruction s) { - if (CF_ADDR) { + private static DefUseEffect int2AddrZerExt(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_REF_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -2996,8 +2959,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect long2Addr(Instruction s) { - if (VM.BuildFor64Addr && CF_ADDR) { + private static DefUseEffect long2Addr(Instruction s, OptOptions opts) { + if (VM.BuildFor64Addr && opts.SIMPLIFY_REF_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -3009,8 +2972,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect int2Short(Instruction s) { - if (CF_INT) { + private static DefUseEffect int2Short(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -3022,8 +2985,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect intBitsAsFloat(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect intBitsAsFloat(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isIntConstant()) { // CONSTANT: FOLD @@ -3035,8 +2998,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect addr2Int(Instruction s) { - if (CF_INT) { + private static DefUseEffect addr2Int(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isConstant() && !op.isMovableObjectConstant()) { // CONSTANT: FOLD @@ -3048,8 +3011,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect addr2Long(Instruction s) { - if (CF_LONG) { + private static DefUseEffect addr2Long(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isConstant() && !op.isMovableObjectConstant()) { // CONSTANT: FOLD @@ -3061,8 +3024,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect float2Double(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect float2Double(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -3074,8 +3037,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect float2Int(Instruction s) { - if (CF_INT) { + private static DefUseEffect float2Int(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -3087,8 +3050,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect float2Long(Instruction s) { - if (CF_LONG) { + private static DefUseEffect float2Long(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_LONG_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -3100,8 +3063,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect floatAsIntBits(Instruction s) { - if (CF_INT) { + private static DefUseEffect floatAsIntBits(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isFloatConstant()) { // CONSTANT: FOLD @@ -3113,8 +3076,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect long2Float(Instruction s) { - if (CF_FLOAT) { + private static DefUseEffect long2Float(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FLOAT_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -3126,8 +3089,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect long2Int(Instruction s) { - if (CF_INT) { + private static DefUseEffect long2Int(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_INTEGER_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -3139,8 +3102,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect long2Double(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect long2Double(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -3152,8 +3115,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect longBitsAsDouble(Instruction s) { - if (CF_DOUBLE) { + private static DefUseEffect longBitsAsDouble(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_DOUBLE_OPS) { Operand op = Unary.getVal(s); if (op.isLongConstant()) { // CONSTANT: FOLD @@ -3165,8 +3128,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect arrayLength(Instruction s) { - if (CF_FIELDS) { + private static DefUseEffect arrayLength(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FIELD_OPS) { Operand op = GuardedUnary.getVal(s); if (op.isObjectConstant()) { int length = 0; @@ -3185,8 +3148,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect boundsCheck(Instruction s) { - if (CF_FIELDS) { + private static DefUseEffect boundsCheck(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FIELD_OPS) { Operand ref = BoundsCheck.getRef(s); Operand index = BoundsCheck.getIndex(s); if (ref.isNullConstant()) { @@ -3214,8 +3177,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect call(boolean HIR, AbstractRegisterPool regpool, Instruction s) { - if (CF_FIELDS) { + private static DefUseEffect call(boolean HIR, AbstractRegisterPool regpool, Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FIELD_OPS) { MethodOperand methOp = Call.getMethod(s); if (methOp == null) { return DefUseEffect.UNCHANGED; @@ -3399,8 +3362,8 @@ } } - private static DefUseEffect getField(Instruction s) { - if (CF_FIELDS) { + private static DefUseEffect getField(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_FIELD_OPS) { Operand ref = GetField.getRef(s); if (VM.VerifyAssertions && ref.isNullConstant()) { // Simplify to an unreachable operand, this instruction is dead code @@ -3408,7 +3371,7 @@ RegisterOperand result = GetField.getClearResult(s); Move.mutate(s, IRTools.getMoveOp(result.getType()), result, new UnreachableOperand()); return DefUseEffect.MOVE_FOLDED; - } else if (ref.isObjectConstant()) { + } else if (opts.SIMPLIFY_CHASE_FINAL_FIELDS && ref.isObjectConstant()) { // A constant object references this field which is // final. As the reference is final the constructor // of the referred object MUST have already completed. @@ -3434,8 +3397,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getObjTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getObjTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { Operand op = GuardedUnary.getVal(s); if (op.isNullConstant()) { // Simplify to an unreachable operand, this instruction is dead code @@ -3468,8 +3431,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getClassTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getClassTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { TypeOperand typeOp = Unary.getVal(s).asType(); if (typeOp.getTypeRef().isResolved()) { Move.mutate(s, @@ -3482,8 +3445,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getTypeFromTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getTypeFromTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { Operand tibOp = Unary.getVal(s); if (tibOp.isTIBConstant()) { TIBConstantOperand tib = tibOp.asTIBConstant(); @@ -3494,8 +3457,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getArrayElementTibFromTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getArrayElementTibFromTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { Operand tibOp = Unary.getVal(s); if (tibOp.isTIBConstant()) { TIBConstantOperand tib = tibOp.asTIBConstant(); @@ -3509,8 +3472,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getSuperclassIdsFromTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getSuperclassIdsFromTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { Operand tibOp = Unary.getVal(s); if (tibOp.isTIBConstant()) { TIBConstantOperand tib = tibOp.asTIBConstant(); @@ -3524,8 +3487,8 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect getDoesImplementFromTib(Instruction s) { - if (CF_TIB) { + private static DefUseEffect getDoesImplementFromTib(Instruction s, OptOptions opts) { + if (opts.SIMPLIFY_TIB_OPS) { Operand tibOp = Unary.getVal(s); if (tibOp.isTIBConstant()) { TIBConstantOperand tib = tibOp.asTIBConstant(); @@ -3540,7 +3503,7 @@ } private static DefUseEffect refLoad(Instruction s, OptOptions opts) { - if (CF_TIB) { + if (opts.SIMPLIFY_TIB_OPS) { Operand base = Load.getAddress(s); if (base.isTIBConstant()) { TIBConstantOperand tib = base.asTIBConstant(); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-20 22:57:43 UTC (rev 15233) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-12-20 23:00:01 UTC (rev 15234) @@ -1599,7 +1599,7 @@ // initialized or we're writing the bootimage and in an // RVM bootimage class, then get the value at compile // time. - if (field.isFinal()) { + if (gc.options.SIMPLIFY_CHASE_FINAL_FIELDS && field.isFinal()) { RVMClass declaringClass = field.getDeclaringClass(); if (declaringClass.isInitialized() || declaringClass.isInBootImage()) { try { Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-20 22:57:43 UTC (rev 15233) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-20 23:00:01 UTC (rev 15234) @@ -45,6 +45,37 @@ Pre-existence based inlining ########## +# Simplifier, single instruction optimizations +# NB: these operations may create more literal values that may consume space +# in the JTOC. +# NB: The convention is that constant folding is controlled based on the type +# of the result of the operator, not the type of... [truncated message content] |
From: <cap...@us...> - 2008-12-22 23:05:21
|
Revision: 15237 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15237&view=rev Author: captain5050 Date: 2008-12-22 23:05:13 +0000 (Mon, 22 Dec 2008) Log Message: ----------- PPC build fixes. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/PrePassScheduler.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/Scheduler.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/ComplexLIR2MIRExpansion.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/NormalizeConstants.java rvmroot/trunk/rvm/src-generated/opt-burs/ppc/PPC_Common.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/PrePassScheduler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/PrePassScheduler.java 2008-12-22 23:03:40 UTC (rev 15236) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/PrePassScheduler.java 2008-12-22 23:05:13 UTC (rev 15237) @@ -24,7 +24,7 @@ public final class PrePassScheduler extends CompilerPhase { public boolean shouldPerform(OptOptions options) { - return options.SCHEDULE_PREPASS; + return options.L2M_SCHEDULE_PREPASS; } public String getName() { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/Scheduler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/Scheduler.java 2008-12-22 23:03:40 UTC (rev 15236) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/instrsched/Scheduler.java 2008-12-22 23:05:13 UTC (rev 15237) @@ -127,7 +127,7 @@ } // Performing live analysis may reduce dependences between PEIs and stores - if (ir.options.HANDLER_LIVENESS) { + if (ir.options.L2M_HANDLER_LIVENESS) { new LiveAnalysis(false, false, true).perform(ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/ComplexLIR2MIRExpansion.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/ComplexLIR2MIRExpansion.java 2008-12-22 23:03:40 UTC (rev 15236) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/ComplexLIR2MIRExpansion.java 2008-12-22 23:05:13 UTC (rev 15237) @@ -487,7 +487,7 @@ } private static void long_ifcmp(Instruction s, IR ir) { - if (VM.VerifyAssertions) VM._assert(!IfCmp.getCond(s).isUNSIGNED()); + if (VM.VerifyAssertions) VM._assert(IfCmp.getCond(s).isEQUAL() || IfCmp.getCond(s).isNOT_EQUAL() || !IfCmp.getCond(s).isUNSIGNED()); BasicBlock BB1 = s.getBasicBlock(); BasicBlock BB3 = BB1.splitNodeAt(s, ir); BasicBlock BB2 = BB1.createSubBlock(0, ir); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/NormalizeConstants.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/NormalizeConstants.java 2008-12-22 23:03:40 UTC (rev 15236) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ppc/NormalizeConstants.java 2008-12-22 23:05:13 UTC (rev 15237) @@ -190,9 +190,8 @@ // This code assumes that INT/LONG/ADDR constant folding in Simplifier is enabled. // This greatly reduces the number of cases we have to worry about below. - if (!(Simplifier.CF_INT && Simplifier.CF_LONG && Simplifier.CF_ADDR)) { - throw new OptimizingCompilerException("Unexpected config!"); - } + if (VM.VerifyAssertions) VM._assert(ir.options.SIMPLIFY_INTEGER_OPS && ir.options.SIMPLIFY_LONG_OPS && ir.options.SIMPLIFY_REF_OPS); + for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) { // STEP ONE: Get 'large' constants into a form that the PPC BURS rules @@ -290,7 +289,7 @@ // in normalized form. This reduces the number of cases we have to // worry about (and does last minute constant folding on the off chance // we've missed an opportunity...) - Simplifier.simplify(false, ir.regpool, s); + Simplifier.simplify(false, ir.regpool, ir.options, s); switch (s.getOpcode()) { ////////// Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ppc/PPC_Common.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ppc/PPC_Common.rules 2008-12-22 23:03:40 UTC (rev 15236) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ppc/PPC_Common.rules 2008-12-22 23:05:13 UTC (rev 15237) @@ -815,84 +815,84 @@ # FMA and friends ##### r: FLOAT_ADD(FLOAT_MUL(r, r), r) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMADDS, Binary.getResult(P(p)), \ R(Binary.getVal1(PL(p))), R(Binary.getVal2(PL(p))), \ R(Binary.getVal2(P(p))))); r: DOUBLE_ADD(DOUBLE_MUL(r, r), r) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMADD, Binary.getResult(P(p)), \ R(Binary.getVal1(PL(p))), R(Binary.getVal2(PL(p))), \ R(Binary.getVal2(P(p))))); r: FLOAT_ADD(r, FLOAT_MUL(r,r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PR(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMADDS, Binary.getResult(P(p)), \ R(Binary.getVal1(PR(p))), R(Binary.getVal2(PR(p))), \ R(Binary.getVal1(P(p))))); r: DOUBLE_ADD(r, DOUBLE_MUL(r,r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PR(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMADD, Binary.getResult(P(p)), \ R(Binary.getVal1(PR(p))), R(Binary.getVal2(PR(p))), \ R(Binary.getVal1(P(p))))); r: FLOAT_SUB(FLOAT_MUL(r, r), r) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMSUBS, Binary.getResult(P(p)), \ R(Binary.getVal1(PL(p))), R(Binary.getVal2(PL(p))), \ R(Binary.getVal2(P(p))))); r: DOUBLE_SUB(DOUBLE_MUL(r, r), r) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FMSUB, Binary.getResult(P(p)), \ R(Binary.getVal1(PL(p))), R(Binary.getVal2(PL(p))), \ R(Binary.getVal2(P(p))))); r: FLOAT_NEG(FLOAT_ADD(FLOAT_MUL(r, r), r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMADDS, Binary.getResult(P(p)), \ R(Binary.getVal1(PLL(p))), R(Binary.getVal2(PLL(p))), \ R(Binary.getVal2(PL(p))))); r: DOUBLE_NEG(DOUBLE_ADD(DOUBLE_MUL(r, r), r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMADD, Binary.getResult(P(p)), \ R(Binary.getVal1(PLL(p))), R(Binary.getVal2(PLL(p))), \ R(Binary.getVal2(PL(p))))); r: FLOAT_NEG(FLOAT_ADD(r, FLOAT_MUL(r,r))) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLR(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMADDS, Binary.getResult(P(p)), \ R(Binary.getVal1(PLR(p))), R(Binary.getVal2(PLR(p))), \ R(Binary.getVal1(PL(p))))); r: DOUBLE_NEG(DOUBLE_ADD(r, DOUBLE_MUL(r,r))) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLR(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMADD, Binary.getResult(P(p)), \ R(Binary.getVal1(PLR(p))), R(Binary.getVal2(PLR(p))),\ R(Binary.getVal1(PL(p))))); r: FLOAT_NEG(FLOAT_SUB(FLOAT_MUL(r, r), r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMSUBS, Binary.getResult(P(p)), \ R(Binary.getVal1(PLL(p))), R(Binary.getVal2(PLL(p))), \ R(Binary.getVal2(PL(p))))); r: DOUBLE_NEG(DOUBLE_SUB(DOUBLE_MUL(r, r), r)) -burs.ir.options.strictFP()?INFINITE:10 +burs.ir.strictFP(P(p),PL(p),PLL(p))?INFINITE:10 EMIT_INSTRUCTION EMIT(MIR_Ternary.mutate(P(p), PPC_FNMSUB, Binary.getResult(P(p)), \ R(Binary.getVal1(PLL(p))), R(Binary.getVal2(PLL(p))), \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-28 23:01:42
|
Revision: 15239 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15239&view=rev Author: captain5050 Date: 2008-12-28 23:01:39 +0000 (Sun, 28 Dec 2008) Log Message: ----------- RVM-725: make leave SSA options configurable via options. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LeaveSSA.java rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LeaveSSA.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LeaveSSA.java 2008-12-25 08:29:58 UTC (rev 15238) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/LeaveSSA.java 2008-12-28 23:01:39 UTC (rev 15239) @@ -67,11 +67,6 @@ */ static final boolean DEBUG = false; - // control bias between adding blocks or adding temporaries - private static final boolean SplitBlockToAvoidRenaming = false; - private static final boolean SplitBlockForLocalLive = true; - private static final boolean SplitBlockIntoInfrequent = true; - /** * The IR to manipulate */ @@ -391,10 +386,10 @@ if (c.source.isRegister()) rr = c.source.asRegister().getRegister(); boolean shouldSplitBlock = !c.phi.getBasicBlock().isExceptionHandlerBasicBlock() && - ((out.contains(r) && SplitBlockToAvoidRenaming) || - (rr != null && usedBelowCopy(bb, rr) && SplitBlockForLocalLive)); + ((ir.options.SSA_SPLITBLOCK_TO_AVOID_RENAME && out.contains(r)) || + (rr != null && ir.options.SSA_SPLITBLOCK_FOR_LOCAL_LIVE && usedBelowCopy(bb, rr))); - if (SplitBlockIntoInfrequent) { + if (ir.options.SSA_SPLITBLOCK_INTO_INFREQUENT) { if (!bb.getInfrequent() && c.phi.getBasicBlock().getInfrequent() && !c.phi.getBasicBlock().isExceptionHandlerBasicBlock()) { Modified: rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-25 08:29:58 UTC (rev 15238) +++ rvmroot/trunk/rvm/src-generated/options/BooleanOptions.opt.dat 2008-12-28 23:01:39 UTC (rev 15239) @@ -152,6 +152,15 @@ SSA_GLOBAL_BOUNDS_CHECK -1 false ssa_global_bounds Perform (incomplete/unsafe) global Array Bound Check elimination on Demand +SSA_SPLITBLOCK_TO_AVOID_RENAME -1 false +When leaving SSA create blocks to avoid renaming variables + +SSA_SPLITBLOCK_FOR_LOCAL_LIVE -1 true +When leaving SSA create blocks for local liveness + +SSA_SPLITBLOCK_INTO_INFREQUENT -1 true +When leaving SSA create blocks to avoid adding code to frequently executed blocks + ########## # Code reordering for icache performance options ########## This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-29 23:55:51
|
Revision: 15242 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15242&view=rev Author: captain5050 Date: 2008-12-29 23:55:42 +0000 (Mon, 29 Dec 2008) Log Message: ----------- RVM-362: Sort uses on commutative operators prior to IA32 BURS placing those with the most defs on the lhs. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizationPlanner.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/recompilation/instrumentation/InstrumentationSamplingFramework.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -164,7 +164,7 @@ private void cleanUp(IR ir) { // Clean up the ir with simple optimizations - Simple simple = new Simple(-1, false, false, false); + Simple simple = new Simple(-1, false, false, false, false); simple.perform(ir); // Perform branch optimizations (level 0 is passed because if we Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simple.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -28,6 +28,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; +import java.util.Enumeration; import org.jikesrvm.VM; import org.jikesrvm.compilers.opt.controlflow.BranchOptimizations; @@ -35,6 +36,7 @@ import org.jikesrvm.compilers.opt.driver.CompilerPhase; import org.jikesrvm.compilers.opt.ir.BasicBlock; import org.jikesrvm.compilers.opt.ir.BasicBlockEnumeration; +import org.jikesrvm.compilers.opt.ir.Binary; import org.jikesrvm.compilers.opt.ir.BoundsCheck; import org.jikesrvm.compilers.opt.ir.GuardedUnary; import org.jikesrvm.compilers.opt.ir.IR; @@ -76,6 +78,10 @@ * Fold conditional branches with constant operands? */ private final boolean foldBranches; + /** + * Sort registers used by commutative operators + */ + private final boolean sortRegisters; public boolean shouldPerform(OptOptions options) { return options.getOptLevel() >= level; @@ -99,14 +105,16 @@ * @param typeProp should type propagation be peformed? * @param foldChecks should we attempt to eliminate boundscheck? * @param foldBranches should we attempt to constant fold conditional + * @param sortRegisters should we sort use operands? * branches? */ - public Simple(int level, boolean typeProp, boolean foldChecks, boolean foldBranches) { - super(new Object[]{level, typeProp, foldChecks, foldBranches}); + public Simple(int level, boolean typeProp, boolean foldChecks, boolean foldBranches, boolean sortRegisters) { + super(new Object[]{level, typeProp, foldChecks, foldBranches, sortRegisters}); this.level = level; this.typeProp = typeProp; this.foldChecks = foldChecks; this.foldBranches = foldBranches; + this.sortRegisters = sortRegisters; } /** @@ -114,7 +122,7 @@ */ private static final Constructor<CompilerPhase> constructor = getCompilerPhaseConstructor(Simple.class, - new Class[]{Integer.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE}); + new Class[]{Integer.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE, Boolean.TYPE}); /** * Get a constructor object for this compiler phase @@ -165,9 +173,51 @@ if (foldBranches) { simplifyConstantBranches(ir); } + // Should we sort commutative use operands + if (sortRegisters) { + sortCommutativeRegisterUses(ir); + } } /** + * Sort commutative use operands so that those defined most are on the lhs + * + * @param ir the IR to work on + */ + private static void sortCommutativeRegisterUses(IR ir) { + // Pass over instructions + for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements();) { + Instruction s = e.nextElement(); + // Sort most frequently defined operands onto lhs + if (Binary.conforms(s) && s.operator.isCommutative() && + Binary.getVal1(s).isRegister() && Binary.getVal2(s).isRegister()) { + RegisterOperand rop1 = Binary.getVal1(s).asRegister(); + RegisterOperand rop2 = Binary.getVal2(s).asRegister(); + // Simple SSA based test + if (rop1.register.isSSA()) { + if(rop2.register.isSSA()) { + // ordering is arbitrary, ignore + } else { + // swap + Binary.setVal1(s, rop2); + Binary.setVal2(s, rop1); + } + } else if (rop2.register.isSSA()) { + // already have prefered ordering + } else { + // neither registers are SSA so place registers used more on the RHS + // (we don't have easy access to a count of the number of definitions) + if (rop1.register.useCount > rop2.register.useCount) { + // swap + Binary.setVal1(s, rop2); + Binary.setVal2(s, rop1); + } + } + } + } + } + + /** * Perform flow-insensitive copy and constant propagation using * register list information. * Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/LoopUnrolling.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -96,7 +96,7 @@ if (ir.hasReachableExceptionHandlers()) return; DefUse.computeDU(ir); - new Simple(1, true, true, true).perform(ir); + new Simple(1, true, true, true, false).perform(ir); new BranchOptimizations(-1, true, true).perform(ir, true); //new CFGTransformations().perform(ir); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizationPlanner.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizationPlanner.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/driver/OptimizationPlanner.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -250,7 +250,7 @@ new Object[]{new BuildLST(), new YieldPoints(), new EstimateBlockFrequencies()}); // Simple flow-insensitive optimizations - addComponent(p, new Simple(1, true, true, false)); + addComponent(p, new Simple(1, true, true, false, false)); // Simple escape analysis and related transformations addComponent(p, new EscapeTransformations()); @@ -345,7 +345,7 @@ new OptimizationPlanCompositeElement("Post SSA cleanup", new Object[]{new LocalCopyProp(), new LocalConstantProp(), - new Simple(3, true, true, false), + new Simple(3, true, true, false, false), new EscapeTransformations(), new BranchOptimizations(3, true, true)}) { public boolean shouldPerform(OptOptions options) { @@ -395,7 +395,7 @@ new OptimizationPlanCompositeElement("Post SSA cleanup", new Object[]{new LocalCopyProp(), new LocalConstantProp(), - new Simple(3, true, true, false), + new Simple(3, true, true, false, false), new BranchOptimizations(3, true, true)}) { public boolean shouldPerform(OptOptions options) { return options.getOptLevel() >= 3; @@ -455,7 +455,7 @@ // Perform local common-subexpression elimination for a factored basic block. addComponent(p, new LocalCSE(false)); // Simple flow-insensitive optimizations - addComponent(p, new Simple(0, false, false, false)); + addComponent(p, new Simple(0, false, false, false, VM.BuildForIA32)); // Use the LST to estimate basic block frequency addComponent(p, Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/EscapeTransformations.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -53,7 +53,7 @@ OptimizationPlanCompositeElement.compose("Clean up escape transformations", new Object[]{new LocalCopyProp(), new LocalConstantProp(), - new Simple(0, true, false, false)}); + new Simple(0, true, false, false, false)}); /** * Return this instance of this phase. This phase contains no Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/escape/SimpleEscape.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -815,7 +815,7 @@ private static OptimizationPlanElement initEscapePlan() { return OptimizationPlanCompositeElement.compose("Escape Analysis", new Object[]{new ConvertBCtoHIR(), - new Simple(1, true, true, false), + new Simple(1, true, true, false, false), new SimpleEscape()}); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/ExpandRuntimeServices.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -532,7 +532,7 @@ } branchOpts.perform(ir, true); if (_os == null) { - _os = new Simple(1, false, false, false); + _os = new Simple(1, false, false, false, false); } _os.perform(ir); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ssa/SSATuneUp.java 2008-12-29 23:55:42 UTC (rev 15242) @@ -42,7 +42,7 @@ // 2. Get the desired SSA form new OptimizationPlanAtomicElement(new EnterSSA()), // 3. Perform simple optimizations - new OptimizationPlanAtomicElement(new Simple(1, true, true, false)), + new OptimizationPlanAtomicElement(new Simple(1, true, true, false, false)), // 4. Perform expression simplification new OptimizationPlanAtomicElement(new FoldingDriver())}); } Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2008-12-29 23:52:13 UTC (rev 15241) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2008-12-29 23:55:42 UTC (rev 15242) @@ -28,15 +28,10 @@ # ADD ##### r: FLOAT_ADD(r, r) -p.child1.isREGISTERNode() ? 11 : 13 +13 EMIT_INSTRUCTION SSE2_COP(IA32_ADDSS, P(p), Binary.getResult(P(p)), Binary.getVal1(P(p)), Binary.getVal2(P(p))); -r: FLOAT_ADD(r, r) -p.child2.isREGISTERNode() ? 11 : 13 -EMIT_INSTRUCTION -SSE2_COP(IA32_ADDSS, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), Binary.getVal1(P(p))); - r: FLOAT_ADD(r, float_load) 15 EMIT_INSTRUCTION @@ -48,13 +43,8 @@ SSE2_COP(IA32_ADDSS, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), consumeMO()); r: DOUBLE_ADD(r, r) -p.child1.isREGISTERNode() ? 11 : 13 +13 EMIT_INSTRUCTION -SSE2_COP(IA32_ADDSD, P(p), Binary.getResult(P(p)), Binary.getVal1(P(p)), Binary.getVal2(P(p))); - -r: DOUBLE_ADD(r, r) -p.child2.isREGISTERNode() ? 11 : 13 -EMIT_INSTRUCTION SSE2_COP(IA32_ADDSD, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), Binary.getVal1(P(p))); r: DOUBLE_ADD(r, double_load) @@ -94,15 +84,10 @@ # MUL ##### r: FLOAT_MUL(r, r) -p.child1.isREGISTERNode() ? 11 : 13 +13 EMIT_INSTRUCTION SSE2_COP(IA32_MULSS, P(p), Binary.getResult(P(p)), Binary.getVal1(P(p)), Binary.getVal2(P(p))); -r: FLOAT_MUL(r, r) -p.child2.isREGISTERNode() ? 11 : 13 -EMIT_INSTRUCTION -SSE2_COP(IA32_MULSS, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), Binary.getVal1(P(p))); - r: FLOAT_MUL(r, float_load) 15 EMIT_INSTRUCTION @@ -114,15 +99,10 @@ SSE2_COP(IA32_MULSS, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), consumeMO()); r: DOUBLE_MUL(r, r) -p.child1.isREGISTERNode() ? 11 : 13 +13 EMIT_INSTRUCTION SSE2_COP(IA32_MULSD, P(p), Binary.getResult(P(p)), Binary.getVal1(P(p)), Binary.getVal2(P(p))); -r: DOUBLE_MUL(r, r) -p.child2.isREGISTERNode() ? 11 : 13 -EMIT_INSTRUCTION -SSE2_COP(IA32_MULSD, P(p), Binary.getResult(P(p)), Binary.getVal2(P(p)), Binary.getVal1(P(p))); - r: DOUBLE_MUL(r, double_load) 15 EMIT_INSTRUCTION This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2008-12-31 20:24:11
|
Revision: 15243 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15243&view=rev Author: captain5050 Date: 2008-12-31 20:24:06 +0000 (Wed, 31 Dec 2008) Log Message: ----------- RVM-740: support for conditional moves on Intel with SSE2. Also enable conditional moves in the boot image as performance runs are now with profile data. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2008-12-31 20:24:06 UTC (rev 15243) @@ -12,30 +12,13 @@ */ package org.jikesrvm.compilers.opt.controlflow; -import java.util.HashMap; -import java.util.HashSet; -import org.jikesrvm.VM; -import org.jikesrvm.classloader.TypeReference; -import org.jikesrvm.compilers.opt.OptimizingCompilerException; -import org.jikesrvm.compilers.opt.ir.BooleanCmp; -import org.jikesrvm.compilers.opt.ir.CondMove; -import org.jikesrvm.compilers.opt.ir.Goto; -import org.jikesrvm.compilers.opt.ir.IfCmp; -import org.jikesrvm.compilers.opt.ir.IfCmp2; -import org.jikesrvm.compilers.opt.ir.InlineGuard; -import org.jikesrvm.compilers.opt.ir.Move; -import org.jikesrvm.compilers.opt.ir.BasicBlock; -import org.jikesrvm.compilers.opt.ir.IR; -import org.jikesrvm.compilers.opt.ir.IRTools; import static org.jikesrvm.compilers.opt.ir.IRTools.CPOS; -import org.jikesrvm.compilers.opt.ir.Instruction; -import org.jikesrvm.compilers.opt.ir.InstructionEnumeration; -import org.jikesrvm.compilers.opt.ir.OperandEnumeration; -import org.jikesrvm.compilers.opt.ir.Operator; import static org.jikesrvm.compilers.opt.ir.Operators.BBEND; import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_CMP_ADDR; import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_CMP_INT; import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_NOT; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_MOVE_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_MOVE_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.GOTO; import static org.jikesrvm.compilers.opt.ir.Operators.INT_2BYTE_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.INT_2SHORT_opcode; @@ -67,6 +50,27 @@ import static org.jikesrvm.compilers.opt.ir.Operators.REF_USHR_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.REF_XOR_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.RETURN; + +import java.util.HashMap; +import java.util.HashSet; + +import org.jikesrvm.VM; +import org.jikesrvm.classloader.TypeReference; +import org.jikesrvm.compilers.opt.OptimizingCompilerException; +import org.jikesrvm.compilers.opt.ir.BasicBlock; +import org.jikesrvm.compilers.opt.ir.BooleanCmp; +import org.jikesrvm.compilers.opt.ir.CondMove; +import org.jikesrvm.compilers.opt.ir.Goto; +import org.jikesrvm.compilers.opt.ir.IR; +import org.jikesrvm.compilers.opt.ir.IRTools; +import org.jikesrvm.compilers.opt.ir.IfCmp; +import org.jikesrvm.compilers.opt.ir.IfCmp2; +import org.jikesrvm.compilers.opt.ir.InlineGuard; +import org.jikesrvm.compilers.opt.ir.Instruction; +import org.jikesrvm.compilers.opt.ir.InstructionEnumeration; +import org.jikesrvm.compilers.opt.ir.Move; +import org.jikesrvm.compilers.opt.ir.OperandEnumeration; +import org.jikesrvm.compilers.opt.ir.Operator; import org.jikesrvm.compilers.opt.ir.Register; import org.jikesrvm.compilers.opt.ir.Return; import org.jikesrvm.compilers.opt.ir.Unary; @@ -674,44 +678,64 @@ * @return true if the transformation succeeds, false otherwise */ private boolean generateCondMove(IR ir, BasicBlock bb, Instruction cb) { + final boolean VERBOSE=false; if (!VM.BuildForIA32) return false; if (!IfCmp.conforms(cb)) return false; + if (VERBOSE) System.out.println("CondMove: Looking to optimize "+cb); + // Don't generate CMOVs for branches that can be folded. + if (IfCmp.getVal1(cb).isConstant() && IfCmp.getVal2(cb).isConstant()) { + if (VERBOSE) System.out.println("CondMove: fail - could be folded"); + return false; + } + // see if bb is the root of an if-then-else. Diamond diamond = Diamond.buildDiamond(bb); - if (diamond == null) return false; + if (diamond == null) { + if (VERBOSE) System.out.println("CondMove: fail - no diamond"); + return false; + } BasicBlock taken = diamond.getTaken(); BasicBlock notTaken = diamond.getNotTaken(); // do not perform the transformation if either branch of the diamond // has a taboo instruction (eg., a PEI, store or divide). - if (taken != null && hasCMTaboo(taken)) return false; - if (notTaken != null && hasCMTaboo(notTaken)) return false; + if (taken != null && hasCMTaboo(taken)) { + if (VERBOSE) System.out.println("CondMove: fail - taken branch has taboo instruction"); + return false; + } + if (notTaken != null && hasCMTaboo(notTaken)) { + if (VERBOSE) System.out.println("CondMove: fail - not taken branch has taboo instruction"); + return false; + } // Do not generate when we don't know the branch probability or // when branch probability is high. CMOVs reduce performance of // the out-of-order engine (Intel Optimization Guide - // Assembly/Compiler Coding Rule 2) BranchProfileOperand profile = IfCmp.getBranchProfile(cb); - if (!VM.runningVM || - (profile.takenProbability >= BranchProfileOperand.LIKELY) || + if ((profile.takenProbability >= BranchProfileOperand.LIKELY) || (profile.takenProbability <= BranchProfileOperand.UNLIKELY)) { + if (VERBOSE) + System.out.println("CondMove: fail - branch could be well predicted by branch predictor: "+ + profile.takenProbability); return false; } // if we must generate FCMP, make sure the condition code is OK ConditionOperand cond = IfCmp.getCond(cb); if (cond.isFLOATINGPOINT()) { - if (VM.BuildForSSE2Full) { - // No conditional FP moves with SSE2 - return false; - } if (!fpConditionOK(cond)) { // Condition not OK, but maybe if we flip the operands if (!fpConditionOK(cond.flipOperands())) { - // still not ok so flip operands back and give up + // still not ok so flip operands back cond.flipOperands(); - return false; + // give up or for SSE2 check if this is a floating point compare + // controlling just floating point moves + if (!VM.BuildForSSE2Full || hasFloatingPointDef(taken, true) || hasFloatingPointDef(notTaken, true)) { + if (VERBOSE) System.out.println("CondMove: fail - fp condition not OK: "+cond); + return false; + } } else { // flip operands Operand val1 = IfCmp.getVal1(cb); @@ -722,18 +746,18 @@ } } - // Can only generate FMOV instructions for FP and unsigned int compares - if (!cond.isFLOATINGPOINT() || !cond.isUNSIGNED()) { - if (hasFloatingPointDef(taken) || hasFloatingPointDef(notTaken)) { - return false; + if (!cond.isFLOATINGPOINT()) { + // Can only generate moves of floating point values for floating point + // compares or for unsigned compares in x87 + if (VM.BuildForSSE2Full || !cond.isUNSIGNED()) { + if (hasFloatingPointDef(taken, false) || hasFloatingPointDef(notTaken, false)) { + if (VERBOSE) + System.out.println("CondMove: fail - not allowed integer condition controlling floating conditional move"); + return false; + } } } - // Don't generate CMOVs for branches that can be folded. - if (IfCmp.getVal1(cb).isConstant() && IfCmp.getVal2(cb).isConstant()) { - return false; - } - // For now, do not generate CMOVs for longs. if (hasLongDef(taken) || hasLongDef(notTaken)) { return false; @@ -750,7 +774,10 @@ int shortestCost = Math.min(takenCost, notTakenCost); int xformCost = 2 * (takenCost + notTakenCost); int k = ir.options.CONTROL_COND_MOVE_CUTOFF; - if (xformCost - shortestCost > k) return false; + if (xformCost - shortestCost > k) { + if (VERBOSE) System.out.println("CondMove: fail - cost too high"); + return false; + } // Perform the transformation! doCondMove(ir, diamond, cb); @@ -769,45 +796,48 @@ // left == right 1 0 0 // UNORDERED 1 1 1 switch (c.value) { - case ConditionOperand.CMPL_EQUAL: - return false; // (ZF == 1) but ordered - case ConditionOperand.CMPL_NOT_EQUAL: - return false; // (ZF == 0) but unordered - case ConditionOperand.CMPG_LESS: - return false; // (CF == 1) but ordered - case ConditionOperand.CMPG_GREATER_EQUAL: - return false; // (CF == 0) but unordered - case ConditionOperand.CMPG_LESS_EQUAL: - return false; // (CF == 1 || ZF == 1) but ordered - case ConditionOperand.CMPG_GREATER: - return false; // (CF == 0 && ZF == 0) but unordered + case ConditionOperand.CMPL_EQUAL: + return false; // (ZF == 1) but ordered + case ConditionOperand.CMPL_NOT_EQUAL: + return false; // (ZF == 0) but unordered + case ConditionOperand.CMPG_LESS: + return false; // (CF == 1) but ordered + case ConditionOperand.CMPG_GREATER_EQUAL: + return false; // (CF == 0) but unordered + case ConditionOperand.CMPG_LESS_EQUAL: + return false; // (CF == 1 || ZF == 1) but ordered + case ConditionOperand.CMPG_GREATER: + return false; // (CF == 0 && ZF == 0) but unordered - case ConditionOperand.CMPL_GREATER: - return true; // (CF == 0 && ZF == 0) and ordered - case ConditionOperand.CMPL_LESS_EQUAL: - return true; // (CF == 1 || ZF == 1) and unordered - case ConditionOperand.CMPL_GREATER_EQUAL: - return true; // (CF == 0) and ordered - case ConditionOperand.CMPL_LESS: - return true; // (CF == 1) and unordered - default: - OptimizingCompilerException.UNREACHABLE(); - return false; // keep jikes happy + case ConditionOperand.CMPL_GREATER: + return true; // (CF == 0 && ZF == 0) and ordered + case ConditionOperand.CMPL_LESS_EQUAL: + return true; // (CF == 1 || ZF == 1) and unordered + case ConditionOperand.CMPL_GREATER_EQUAL: + return true; // (CF == 0) and ordered + case ConditionOperand.CMPL_LESS: + return true; // (CF == 1) and unordered + default: + OptimizingCompilerException.UNREACHABLE(); + return false; // keep jikes happy } } /** * Do any of the instructions in a basic block define a floating-point * register? + * + * @param bb basic block to search + * @param invert invert the sense of the search */ - private boolean hasFloatingPointDef(BasicBlock bb) { + private static boolean hasFloatingPointDef(BasicBlock bb, boolean invert) { if (bb == null) return false; for (InstructionEnumeration e = bb.forwardRealInstrEnumerator(); e.hasMoreElements();) { Instruction s = e.nextElement(); for (OperandEnumeration d = s.getDefs(); d.hasMoreElements();) { Operand def = d.nextElement(); if (def.isRegister()) { - if (def.asRegister().getRegister().isFloatingPoint()) return true; + if (def.asRegister().getRegister().isFloatingPoint() != invert) return true; } } } @@ -851,6 +881,8 @@ switch (s.operator.opcode) { case INT_MOVE_opcode: case REF_MOVE_opcode: + case DOUBLE_MOVE_opcode: + case FLOAT_MOVE_opcode: case INT_ADD_opcode: case REF_ADD_opcode: case INT_SUB_opcode: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2008-12-31 20:24:06 UTC (rev 15243) @@ -12,40 +12,6 @@ */ package org.jikesrvm.compilers.opt.lir2mir.ia32; -import org.jikesrvm.VM; -import org.jikesrvm.classloader.TypeReference; -import org.jikesrvm.compilers.opt.DefUse; -import org.jikesrvm.compilers.opt.OptimizingCompilerException; -import org.jikesrvm.compilers.opt.ir.Binary; -import org.jikesrvm.compilers.opt.ir.CacheOp; -import org.jikesrvm.compilers.opt.ir.Call; -import org.jikesrvm.compilers.opt.ir.CondMove; -import org.jikesrvm.compilers.opt.ir.GuardedBinary; -import org.jikesrvm.compilers.opt.ir.IfCmp; -import org.jikesrvm.compilers.opt.ir.LowTableSwitch; -import org.jikesrvm.compilers.opt.ir.MIR_BinaryAcc; -import org.jikesrvm.compilers.opt.ir.MIR_Call; -import org.jikesrvm.compilers.opt.ir.MIR_Compare; -import org.jikesrvm.compilers.opt.ir.MIR_CompareExchange; -import org.jikesrvm.compilers.opt.ir.MIR_CompareExchange8B; -import org.jikesrvm.compilers.opt.ir.MIR_CondBranch; -import org.jikesrvm.compilers.opt.ir.MIR_CondMove; -import org.jikesrvm.compilers.opt.ir.MIR_ConvertDW2QW; -import org.jikesrvm.compilers.opt.ir.MIR_Divide; -import org.jikesrvm.compilers.opt.ir.MIR_Lea; -import org.jikesrvm.compilers.opt.ir.MIR_LowTableSwitch; -import org.jikesrvm.compilers.opt.ir.MIR_Move; -import org.jikesrvm.compilers.opt.ir.MIR_Multiply; -import org.jikesrvm.compilers.opt.ir.MIR_Nullary; -import org.jikesrvm.compilers.opt.ir.MIR_RDTSC; -import org.jikesrvm.compilers.opt.ir.MIR_Set; -import org.jikesrvm.compilers.opt.ir.MIR_TrapIf; -import org.jikesrvm.compilers.opt.ir.MIR_Unary; -import org.jikesrvm.compilers.opt.ir.MIR_UnaryAcc; -import org.jikesrvm.compilers.opt.ir.Move; -import org.jikesrvm.compilers.opt.ir.Nullary; -import org.jikesrvm.compilers.opt.ir.Instruction; -import org.jikesrvm.compilers.opt.ir.Operator; import static org.jikesrvm.compilers.opt.ir.Operators.CALL_SAVE_VOLATILE; import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_CMPL; import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_CMPL; @@ -53,10 +19,21 @@ import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ADC; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ADD; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_AND; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDNPD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDNPS; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDPD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ANDPS; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CALL; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CDQ; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMOV; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMP; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPEQSD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPEQSS; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPLESD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPLESS; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPLTSD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CMPLTSS; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_CVTSS2SD; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_FCMOV; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_FCOMI; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_FCOMIP; @@ -92,6 +69,8 @@ import static org.jikesrvm.compilers.opt.ir.Operators.IA32_NEG; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_NOT; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_OR; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ORPD; +import static org.jikesrvm.compilers.opt.ir.Operators.IA32_ORPS; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_RCR; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_RDTSC; import static org.jikesrvm.compilers.opt.ir.Operators.IA32_SAR; @@ -110,10 +89,45 @@ import static org.jikesrvm.compilers.opt.ir.Operators.LONG_SHR; import static org.jikesrvm.compilers.opt.ir.Operators.LONG_USHR; import static org.jikesrvm.compilers.opt.ir.Operators.MIR_LOWTABLESWITCH; + +import org.jikesrvm.VM; +import org.jikesrvm.classloader.TypeReference; +import org.jikesrvm.compilers.opt.DefUse; +import org.jikesrvm.compilers.opt.OptimizingCompilerException; +import org.jikesrvm.compilers.opt.ir.Binary; +import org.jikesrvm.compilers.opt.ir.CacheOp; +import org.jikesrvm.compilers.opt.ir.Call; +import org.jikesrvm.compilers.opt.ir.CondMove; +import org.jikesrvm.compilers.opt.ir.GuardedBinary; +import org.jikesrvm.compilers.opt.ir.IfCmp; +import org.jikesrvm.compilers.opt.ir.Instruction; +import org.jikesrvm.compilers.opt.ir.LowTableSwitch; +import org.jikesrvm.compilers.opt.ir.MIR_BinaryAcc; +import org.jikesrvm.compilers.opt.ir.MIR_Call; +import org.jikesrvm.compilers.opt.ir.MIR_Compare; +import org.jikesrvm.compilers.opt.ir.MIR_CompareExchange; +import org.jikesrvm.compilers.opt.ir.MIR_CompareExchange8B; +import org.jikesrvm.compilers.opt.ir.MIR_CondBranch; +import org.jikesrvm.compilers.opt.ir.MIR_CondMove; +import org.jikesrvm.compilers.opt.ir.MIR_ConvertDW2QW; +import org.jikesrvm.compilers.opt.ir.MIR_Divide; +import org.jikesrvm.compilers.opt.ir.MIR_Lea; +import org.jikesrvm.compilers.opt.ir.MIR_LowTableSwitch; +import org.jikesrvm.compilers.opt.ir.MIR_Move; +import org.jikesrvm.compilers.opt.ir.MIR_Multiply; +import org.jikesrvm.compilers.opt.ir.MIR_Nullary; +import org.jikesrvm.compilers.opt.ir.MIR_RDTSC; +import org.jikesrvm.compilers.opt.ir.MIR_Set; +import org.jikesrvm.compilers.opt.ir.MIR_TrapIf; +import org.jikesrvm.compilers.opt.ir.MIR_Unary; +import org.jikesrvm.compilers.opt.ir.MIR_UnaryAcc; +import org.jikesrvm.compilers.opt.ir.Move; +import org.jikesrvm.compilers.opt.ir.Nullary; +import org.jikesrvm.compilers.opt.ir.Operator; +import org.jikesrvm.compilers.opt.ir.OsrPoint; +import org.jikesrvm.compilers.opt.ir.Prologue; import org.jikesrvm.compilers.opt.ir.Register; import org.jikesrvm.compilers.opt.ir.RegisterOperandEnumeration; -import org.jikesrvm.compilers.opt.ir.OsrPoint; -import org.jikesrvm.compilers.opt.ir.Prologue; import org.jikesrvm.compilers.opt.ir.TrapIf; import org.jikesrvm.compilers.opt.ir.Unary; import org.jikesrvm.compilers.opt.ir.operand.BranchOperand; @@ -1026,6 +1040,76 @@ EMIT(s); // ComplexLIR2MIRExpansion will handle rest of the work. } + private static Operator SSE2_CMP_OP(ConditionOperand cond, boolean single) { + switch(cond.value) { + case ConditionOperand.CMPL_EQUAL: + return single ? IA32_CMPEQSS : IA32_CMPEQSD; + case ConditionOperand.CMPG_LESS: + return single ? IA32_CMPLTSS : IA32_CMPLTSD; + case ConditionOperand.CMPG_LESS_EQUAL: + return single ? IA32_CMPLESS : IA32_CMPLESD; + default: + return null; + } + } + + protected final void SSE2_FCMP_FCMOV(Instruction s) { + Operand lhsCmp = CondMove.getVal1(s); + Operand rhsCmp = CondMove.getVal2(s); + RegisterOperand result = CondMove.getResult(s); + Operand falseValue = CondMove.getFalseValue(s); + Operand trueValue = CondMove.getTrueValue(s); + ConditionOperand cond = CondMove.getCond(s); + final boolean single = result.isFloat(); + + // TODO: support for the MAXSS/MAXSD instructions taking care of NaN cases + // find cmpOperator flipping code or operands as necessary + Operator cmpOperator=SSE2_CMP_OP(cond, single); + boolean needFlipOperands = false; + boolean needFlipCode = false; + if (cmpOperator == null) { + needFlipOperands = !needFlipOperands; + cmpOperator = SSE2_CMP_OP(cond.flipOperands(), single); + if (cmpOperator == null) { + needFlipCode = !needFlipCode; + cmpOperator = SSE2_CMP_OP(cond.flipCode(), single); + if (cmpOperator == null) { + needFlipOperands = !needFlipOperands; + cmpOperator = SSE2_CMP_OP(cond.flipOperands(), single); + if (VM.VerifyAssertions) VM._assert(cmpOperator != null); + } + } + } + if (needFlipOperands) { + Operand temp = lhsCmp; + lhsCmp = rhsCmp; + rhsCmp = temp; + } + if (needFlipCode) { + Operand temp = falseValue; + falseValue = trueValue; + trueValue = temp; + } + // place true value in a temporary register to be used for generation of result + RegisterOperand temp = regpool.makeTemp(result); + EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, temp, trueValue))); + // do compare ensuring size is >= size of result + if (!single && lhsCmp.isFloat()) { + RegisterOperand temp2 = regpool.makeTemp(result); + EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, temp2, rhsCmp))); + EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, result.copyRO(), lhsCmp))); + rhsCmp = temp2; + } else { + if (!result.similar(lhsCmp)) { + EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, result.copyRO(), lhsCmp))); + } + } + EMIT(MIR_BinaryAcc.mutate(s, cmpOperator, result, rhsCmp)); + // result contains all 1s or 0s, use masks and OR to perform conditional move + EMIT(CPOS(s, MIR_Move.create(single ? IA32_ANDPS : IA32_ANDPD, temp.copyRO(), result.copyRO()))); + EMIT(CPOS(s, MIR_Move.create(single ? IA32_ANDNPS : IA32_ANDNPD, result.copyRO(), falseValue))); + EMIT(CPOS(s, MIR_Move.create(single ? IA32_ORPS : IA32_ORPD, result.copyRO(), temp.copyRO()))); + } /** * Expansion of SSE2 floating point constant loads */ @@ -2932,7 +3016,11 @@ // result = cond ? -1 : 0 EMIT(CPOS(s, MIR_BinaryAcc.mutate(s, IA32_SBB, result, result.copyRO()))); if (true_const - false_const != -1) { - EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, result.copyRO(), IC(true_const - false_const)))); + if (true_const - false_const == 1) { + EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, result.copyRO()))); + } else { + EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, result.copyRO(), IC(true_const - false_const)))); + } } if (false_const != 0) { EMIT(MIR_BinaryAcc.create(IA32_ADD, result.copyRO(), IC(false_const))); @@ -2942,7 +3030,11 @@ // result = cond ? 0 : -1 EMIT(CPOS(s, MIR_BinaryAcc.mutate(s, IA32_SBB, result, result.copyRO()))); if (false_const - true_const != -1) { - EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, result.copyRO(), IC(false_const - true_const)))); + if (false_const - true_const == 1) { + EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, result.copyRO()))); + } else { + EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, result.copyRO(), IC(false_const - true_const)))); + } } if (true_const != 0) { EMIT(MIR_BinaryAcc.create(IA32_ADD, result, IC(true_const))); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/regalloc/ia32/RegisterRestrictions.java 2008-12-31 20:24:06 UTC (rev 15243) @@ -219,16 +219,42 @@ } break; + // Instructions that require 16byte alignment (not guaranteed by our + // spills) must be forced to always use registers + case IA32_ANDPS_opcode: + case IA32_ANDNPS_opcode: + case IA32_ORPS_opcode: + case IA32_XORPS_opcode: + case IA32_ANDPD_opcode: + case IA32_ANDNPD_opcode: + case IA32_ORPD_opcode: + case IA32_XORPD_opcode: + return true; + case IA32_ADDSS_opcode: + case IA32_CMPEQSS_opcode: + case IA32_CMPLTSS_opcode: + case IA32_CMPLESS_opcode: + case IA32_CMPUNORDSS_opcode: + case IA32_CMPNESS_opcode: + case IA32_CMPNLTSS_opcode: + case IA32_CMPNLESS_opcode: + case IA32_CMPORDSS_opcode: case IA32_DIVSS_opcode: case IA32_MULSS_opcode: case IA32_SUBSS_opcode: - case IA32_XORPS_opcode: case IA32_ADDSD_opcode: + case IA32_CMPEQSD_opcode: + case IA32_CMPLTSD_opcode: + case IA32_CMPLESD_opcode: + case IA32_CMPUNORDSD_opcode: + case IA32_CMPNESD_opcode: + case IA32_CMPNLTSD_opcode: + case IA32_CMPNLESD_opcode: + case IA32_CMPORDSD_opcode: case IA32_DIVSD_opcode: case IA32_MULSD_opcode: - case IA32_SUBSD_opcode: - case IA32_XORPD_opcode: { + case IA32_SUBSD_opcode: { RegisterOperand op = MIR_BinaryAcc.getResult(s).asRegister(); if (op.getRegister() == r) return true; } Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/Assembler.in 2008-12-31 20:24:06 UTC (rev 15243) @@ -2085,39 +2085,6 @@ //////////////////////////////////////////// /** - * XOR XMM register with other XMM register treating sub-words as floats - * <PRE> - * dstReg ^= srcReg - * </PRE> - */ - @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitXORPS_Reg_Reg(XMM dstReg, XMM srcReg) { - int miStart = mi; - generateREXprefix(false, srcReg, null, dstReg); - setMachineCodes(mi++, (byte) 0x0F); - setMachineCodes(mi++, (byte) 0x57); - emitRegRegOperands(dstReg, srcReg); - if (lister != null) lister.RR(miStart, "XORPS", dstReg, srcReg); - } - - /** - * XOR XMM register with other XMM register treating sub-words as doubles - * <PRE> - * dstReg ^= srcReg - * </PRE> - */ - @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1,2}) - public final void emitXORPD_Reg_Reg(XMM dstReg, XMM srcReg) { - int miStart = mi; - generateREXprefix(false, srcReg, null, dstReg); - setMachineCodes(mi++, (byte) 0x66); - setMachineCodes(mi++, (byte) 0x0F); - setMachineCodes(mi++, (byte) 0x57); - emitRegRegOperands(dstReg, srcReg); - if (lister != null) lister.RR(miStart, "XORPD", dstReg, srcReg); - } - - /** * Empty MMX technology state * <PRE> * emms Modified: rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh =================================================================== --- rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src-generated/ia32-assembler/genAssembler.sh 2008-12-31 20:24:06 UTC (rev 15243) @@ -2948,6 +2948,14 @@ emitSSE2Op none none PSRLQ 0xD3 none none MM MM emitSSE2Op 0x66 none PSLLQ 0xF3 none emitSSE2Op 0x66 none PSRLQ 0xD3 none +emitSSE2Op none none ANDPS 0x54 none +emitSSE2Op 0x66 none ANDPD 0x54 none +emitSSE2Op none none ANDNPS 0x55 none +emitSSE2Op 0x66 none ANDNPD 0x55 none +emitSSE2Op none none ORPS 0x56 none +emitSSE2Op 0x66 none ORPD 0x56 none +emitSSE2Op none none XORPS 0x57 none +emitSSE2Op 0x66 none XORPD 0x57 none emitFloatMemAcc() { local acronym=$1 Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2008-12-31 20:24:06 UTC (rev 15243) @@ -437,6 +437,25 @@ IfCmp.getCond(P(p)).flipOperands(); \ SSE2_IFCMP(IA32_UCOMISD, P(p), IfCmp.getClearVal2(P(p)), consumeMO()); +##### +# FCMP_CMOV +##### +r: FCMP_CMOV(r, OTHER_OPERAND(r, any)) +13 +EMIT_INSTRUCTION +EMIT(CPOS(P(p), MIR_Compare.create(CondMove.getVal1(P(p)).isFloat() ? IA32_UCOMISS : IA32_UCOMISD, \ + CondMove.getVal1(P(p)), CondMove.getVal2(P(p))))); \ +CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ + CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); + +##### +# FCMP_FCMOV +##### +r: FCMP_FCMOV(r, OTHER_OPERAND(r, any)) +13 +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p)); + ###### # Long operations that can use wider registers ##### Modified: rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat 2008-12-29 23:55:42 UTC (rev 15242) +++ rvmroot/trunk/rvm/src-generated/opt-ir/ia32/OperatorList.dat 2008-12-31 20:24:06 UTC (rev 15243) @@ -1189,6 +1189,48 @@ #################### +IA32_ANDPS +MIR_BinaryAcc +none + + + +#################### +IA32_ANDPD +MIR_BinaryAcc +none + + + +#################### +IA32_ANDNPS +MIR_BinaryAcc +none + + + +#################### +IA32_ANDNPD +MIR_BinaryAcc +none + + + +#################### +IA32_ORPS +MIR_BinaryAcc +none + + + +#################### +IA32_ORPD +MIR_BinaryAcc +none + + + +#################### IA32_XORPS MIR_BinaryAcc none This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2009-01-01 18:46:43
|
Revision: 15246 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15246&view=rev Author: captain5050 Date: 2009-01-01 18:46:38 +0000 (Thu, 01 Jan 2009) Log Message: ----------- RVM-741: support for negation and abs using SSE2 bit mask operations. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/BURS_Common_Helpers.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2009-01-01 18:40:42 UTC (rev 15245) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/controlflow/BranchOptimizations.java 2009-01-01 18:46:38 UTC (rev 15246) @@ -17,8 +17,18 @@ import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_CMP_ADDR; import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_CMP_INT; import static org.jikesrvm.compilers.opt.ir.Operators.BOOLEAN_NOT; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_2FLOAT_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_ADD_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_MOVE_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_MUL_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_NEG_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.DOUBLE_SUB_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_2DOUBLE_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_ADD_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_MOVE_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_MUL_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_NEG_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.FLOAT_SUB_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.GOTO; import static org.jikesrvm.compilers.opt.ir.Operators.INT_2BYTE_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.INT_2SHORT_opcode; @@ -885,10 +895,18 @@ case FLOAT_MOVE_opcode: case INT_ADD_opcode: case REF_ADD_opcode: + case FLOAT_ADD_opcode: + case DOUBLE_ADD_opcode: case INT_SUB_opcode: case REF_SUB_opcode: + case FLOAT_SUB_opcode: + case DOUBLE_SUB_opcode: case INT_MUL_opcode: + case FLOAT_MUL_opcode: + case DOUBLE_MUL_opcode: case INT_NEG_opcode: + case FLOAT_NEG_opcode: + case DOUBLE_NEG_opcode: case REF_SHL_opcode: case INT_SHL_opcode: case REF_SHR_opcode: @@ -906,6 +924,8 @@ case INT_2BYTE_opcode: case INT_2USHORT_opcode: case INT_2SHORT_opcode: + case FLOAT_2DOUBLE_opcode: + case DOUBLE_2FLOAT_opcode: // these are OK. break; default: Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/BURS_Common_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/BURS_Common_Helpers.java 2009-01-01 18:40:42 UTC (rev 15245) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/BURS_Common_Helpers.java 2009-01-01 18:46:38 UTC (rev 15246) @@ -276,6 +276,10 @@ return p.child2.child2.child1.getInstruction(); } + protected static Instruction PRRR(BURS_TreeNode p) { + return p.child2.child2.child2.getInstruction(); + } + protected static int V(BURS_TreeNode p) { return ((BURS_IntConstantTreeNode) p).value; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2009-01-01 18:40:42 UTC (rev 15245) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2009-01-01 18:46:38 UTC (rev 15246) @@ -154,6 +154,7 @@ import org.jikesrvm.runtime.Entrypoints; import org.jikesrvm.runtime.Magic; import org.jikesrvm.runtime.RuntimeEntrypoints; +import org.jikesrvm.runtime.Statics; import org.vmmagic.unboxed.Offset; /** @@ -176,6 +177,30 @@ private static final double L2T = Double .parseDouble("3.3219280948873623478083405569094566090"); + /** Mask to flip sign bits in XMM registers */ + private static final Offset floatSignMask = + VM.BuildForSSE2Full ? + Offset.fromIntSignExtend(Statics.findOrCreate16ByteSizeLiteral(0x8000000080000000L, 0x8000000080000000L)) : + Offset.zero(); + + /** Mask to flip sign bits in XMM registers */ + private static final Offset doubleSignMask = + VM.BuildForSSE2Full ? + Offset.fromIntSignExtend(Statics.findOrCreate16ByteSizeLiteral(0x8000000000000000L, 0x8000000000000000L)) : + Offset.zero(); + + /** Mask to abs an XMM registers */ + private static final Offset floatAbsMask = + VM.BuildForSSE2Full ? + Offset.fromIntSignExtend(Statics.findOrCreate16ByteSizeLiteral(0x7FFFFFFF7FFFFFFFL, 0x7FFFFFFF7FFFFFFFL)) : + Offset.zero(); + + /** Mask to abs an XMM registers */ + private static final Offset doubleAbsMask = + VM.BuildForSSE2Full ? + Offset.fromIntSignExtend(Statics.findOrCreate16ByteSizeLiteral(0x7FFFFFFFFFFFFFFFL, 0x7FFFFFFFFFFFFFFFL)) : + Offset.zero(); + /** * When emitting certain rules this holds the condition code state to be * consumed by a parent rule @@ -1011,17 +1036,15 @@ /** * Expansion of SSE2 negation ops */ - protected final void SSE2_NEG(Operator xorOp, Operator subOp, Instruction s, Operand result, Operand value) { + protected final void SSE2_NEG(boolean single, Instruction s, Operand result, Operand value) { if(VM.VerifyAssertions) VM._assert(result.isRegister()); if (!result.similar(value)) { - EMIT(CPOS(s, MIR_BinaryAcc.create(xorOp, result.copy(), result.copy()))); - EMIT(MIR_BinaryAcc.mutate(s, subOp, result, value)); - } else { - RegisterOperand temp = regpool.makeTemp(value.getType()); - EMIT(CPOS(s, MIR_BinaryAcc.create(xorOp, temp.copyRO(), temp))); - EMIT(MIR_BinaryAcc.mutate(s, subOp, temp.copyRO(), value)); - EMIT(CPOS(s, MIR_Move.create(SSE2_MOVE(result), result, temp.copyRO()))); + EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, result.copy(), value))); } + Offset signMaskOffset = single ? floatSignMask : doubleSignMask; + EMIT(MIR_BinaryAcc.mutate(s, single ? IA32_XORPS : IA32_XORPD, result, + MemoryOperand.D(Magic.getTocPointer().plus(signMaskOffset), PARAGRAPH, + new LocationOperand(signMaskOffset), TG()))); } /** @@ -1110,6 +1133,57 @@ EMIT(CPOS(s, MIR_Move.create(single ? IA32_ANDNPS : IA32_ANDNPD, result.copyRO(), falseValue))); EMIT(CPOS(s, MIR_Move.create(single ? IA32_ORPS : IA32_ORPD, result.copyRO(), temp.copyRO()))); } + + protected final boolean IS_MATERIALIZE_ZERO(Instruction s) { + Operand val = Binary.getVal2(s); // float or double value + return (val.isFloatConstant() && Float.floatToRawIntBits(val.asFloatConstant().value) == 0) || + (val.isDoubleConstant() && Double.doubleToRawLongBits(val.asDoubleConstant().value) == 0L); + } + + protected final boolean SIMILAR_REGISTERS(Operand... ops) { + Operand last = null; + for (Operand op : ops) { + if (!op.isRegister() || (last != null && !op.similar(last))) { + return false; + } + last = op; + } + return true; + } + + protected final boolean SSE2_IS_GT_OR_GE(ConditionOperand cond) { + switch(cond.value) { + case ConditionOperand.CMPG_GREATER: + case ConditionOperand.CMPG_GREATER_EQUAL: + case ConditionOperand.CMPL_GREATER: + case ConditionOperand.CMPL_GREATER_EQUAL: + return true; + } + return false; + } + + protected final boolean SSE2_IS_LT_OR_LE(ConditionOperand cond) { + switch(cond.value) { + case ConditionOperand.CMPG_LESS: + case ConditionOperand.CMPG_LESS_EQUAL: + case ConditionOperand.CMPL_LESS: + case ConditionOperand.CMPL_LESS_EQUAL: + return true; + } + return false; + } + + protected final void SSE2_ABS(boolean single, Instruction s, Operand result, Operand value) { + if(VM.VerifyAssertions) VM._assert(result.isRegister()); + if (!result.similar(value)) { + EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, result.copy(), value))); + } + Offset absMaskOffset = single ? floatAbsMask : doubleAbsMask; + EMIT(MIR_BinaryAcc.mutate(s, single ? IA32_ANDPS : IA32_ANDPD, result, + MemoryOperand.D(Magic.getTocPointer().plus(absMaskOffset), PARAGRAPH, + new LocationOperand(absMaskOffset), TG()))); + } + /** * Expansion of SSE2 floating point constant loads */ Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2009-01-01 18:40:42 UTC (rev 15245) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2009-01-01 18:46:38 UTC (rev 15246) @@ -142,12 +142,12 @@ r: FLOAT_NEG(r) 26 EMIT_INSTRUCTION -SSE2_NEG(IA32_XORPS, IA32_SUBSS, P(p), Unary.getResult(P(p)), Unary.getVal(P(p))); +SSE2_NEG(true, P(p), Unary.getResult(P(p)), Unary.getVal(P(p))); r: DOUBLE_NEG(r) 26 EMIT_INSTRUCTION -SSE2_NEG(IA32_XORPD, IA32_SUBSD, P(p), Unary.getResult(P(p)), Unary.getVal(P(p))); +SSE2_NEG(false, P(p), Unary.getResult(P(p)), Unary.getVal(P(p))); ##### # SQRT @@ -441,7 +441,7 @@ # FCMP_CMOV ##### r: FCMP_CMOV(r, OTHER_OPERAND(r, any)) -13 +13*2 EMIT_INSTRUCTION EMIT(CPOS(P(p), MIR_Compare.create(CondMove.getVal1(P(p)).isFloat() ? IA32_UCOMISS : IA32_UCOMISD, \ CondMove.getVal1(P(p)), CondMove.getVal2(P(p))))); \ @@ -452,10 +452,69 @@ # FCMP_FCMOV ##### r: FCMP_FCMOV(r, OTHER_OPERAND(r, any)) -13 +13*4 EMIT_INSTRUCTION SSE2_FCMP_FCMOV(P(p)); +##### +# Absolute +##### +# x > 0 ? x : -x +r: FCMP_FCMOV(r, OTHER_OPERAND(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, FLOAT_NEG(r)))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_GT_OR_GE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal1(P(p)), CondMove.getTrueValue(P(p)), Unary.getVal(PRRR(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(true, P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p))); + +# x < 0 ? -x : x +r: FCMP_FCMOV(r, OTHER_OPERAND(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(FLOAT_NEG(r), r))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_LT_OR_LE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal1(P(p)), CondMove.getFalseValue(P(p)), Unary.getVal(PRRL(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(true, P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p))); + +# 0 > x ? -x : x +r: FCMP_FCMOV(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, OTHER_OPERAND(FLOAT_NEG(r), r))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_GT_OR_GE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal2(P(p)), CondMove.getFalseValue(P(p)), Unary.getVal(PRRL(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(true, P(p), CondMove.getResult(P(p)), CondMove.getVal2(P(p))); + +# 0 < x ? x : -x +r: FCMP_FCMOV(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, OTHER_OPERAND(r, FLOAT_NEG(r)))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_LT_OR_LE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal2(P(p)), CondMove.getTrueValue(P(p)), Unary.getVal(PRRR(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(true, P(p), CondMove.getResult(P(p)), CondMove.getVal2(P(p))); + +# x > 0 ? x : -x +r: FCMP_FCMOV(r, OTHER_OPERAND(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, DOUBLE_NEG(r)))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_GT_OR_GE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal1(P(p)), CondMove.getTrueValue(P(p)), Unary.getVal(PRRR(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(false, P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p))); + +# x < 0 ? -x : x +r: FCMP_FCMOV(r, OTHER_OPERAND(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(DOUBLE_NEG(r), r))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_LT_OR_LE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal1(P(p)), CondMove.getFalseValue(P(p)), Unary.getVal(PRRL(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(false, P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p))); + +# 0 > x ? -x : x +r: FCMP_FCMOV(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, OTHER_OPERAND(DOUBLE_NEG(r), r))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_GT_OR_GE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal2(P(p)), CondMove.getFalseValue(P(p)), Unary.getVal(PRRL(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(false, P(p), CondMove.getResult(P(p)), CondMove.getVal2(P(p))); + +# 0 < x ? x : -x +r: FCMP_FCMOV(MATERIALIZE_FP_CONSTANT(INT_CONSTANT), OTHER_OPERAND(r, OTHER_OPERAND(r, DOUBLE_NEG(r)))) +IS_MATERIALIZE_ZERO(PRL(p)) && SSE2_IS_LT_OR_LE(CondMove.getCond(P(p))) && \ +SIMILAR_REGISTERS(CondMove.getVal2(P(p)), CondMove.getTrueValue(P(p)), Unary.getVal(PRRR(p))) ? 11 : INFINITE +EMIT_INSTRUCTION +SSE2_ABS(false, P(p), CondMove.getResult(P(p)), CondMove.getVal2(P(p))); + ###### # Long operations that can use wider registers ##### This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cap...@us...> - 2009-01-01 23:41:35
|
Revision: 15247 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15247&view=rev Author: captain5050 Date: 2009-01-01 23:41:31 +0000 (Thu, 01 Jan 2009) Log Message: ----------- Memory operands for SSE2 conditional moves. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2009-01-01 18:46:38 UTC (rev 15246) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/lir2mir/ia32/BURS_Helpers.java 2009-01-01 23:41:31 UTC (rev 15247) @@ -1063,7 +1063,7 @@ EMIT(s); // ComplexLIR2MIRExpansion will handle rest of the work. } - private static Operator SSE2_CMP_OP(ConditionOperand cond, boolean single) { + protected static Operator SSE2_CMP_OP(ConditionOperand cond, boolean single) { switch(cond.value) { case ConditionOperand.CMPL_EQUAL: return single ? IA32_CMPEQSS : IA32_CMPEQSD; @@ -1076,29 +1076,25 @@ } } - protected final void SSE2_FCMP_FCMOV(Instruction s) { - Operand lhsCmp = CondMove.getVal1(s); - Operand rhsCmp = CondMove.getVal2(s); - RegisterOperand result = CondMove.getResult(s); - Operand falseValue = CondMove.getFalseValue(s); - Operand trueValue = CondMove.getTrueValue(s); - ConditionOperand cond = CondMove.getCond(s); - final boolean single = result.isFloat(); + protected final void SSE2_FCMP_FCMOV(Instruction s, RegisterOperand result, Operand lhsCmp, Operand rhsCmp, + ConditionOperand cond, Operand trueValue, Operand falseValue) { + final boolean singleResult = result.isFloat(); + final boolean singleCmp = lhsCmp.isFloat(); // TODO: support for the MAXSS/MAXSD instructions taking care of NaN cases // find cmpOperator flipping code or operands as necessary - Operator cmpOperator=SSE2_CMP_OP(cond, single); + Operator cmpOperator=SSE2_CMP_OP(cond, singleCmp); boolean needFlipOperands = false; boolean needFlipCode = false; if (cmpOperator == null) { needFlipOperands = !needFlipOperands; - cmpOperator = SSE2_CMP_OP(cond.flipOperands(), single); + cmpOperator = SSE2_CMP_OP(cond.flipOperands(), singleCmp); if (cmpOperator == null) { needFlipCode = !needFlipCode; - cmpOperator = SSE2_CMP_OP(cond.flipCode(), single); + cmpOperator = SSE2_CMP_OP(cond.flipCode(), singleCmp); if (cmpOperator == null) { needFlipOperands = !needFlipOperands; - cmpOperator = SSE2_CMP_OP(cond.flipOperands(), single); + cmpOperator = SSE2_CMP_OP(cond.flipOperands(), singleCmp); if (VM.VerifyAssertions) VM._assert(cmpOperator != null); } } @@ -1115,23 +1111,24 @@ } // place true value in a temporary register to be used for generation of result RegisterOperand temp = regpool.makeTemp(result); - EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, temp, trueValue))); + EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_MOVSS : IA32_MOVSD, temp, trueValue))); // do compare ensuring size is >= size of result - if (!single && lhsCmp.isFloat()) { + if (!singleResult && singleCmp) { RegisterOperand temp2 = regpool.makeTemp(result); EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, temp2, rhsCmp))); EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, result.copyRO(), lhsCmp))); rhsCmp = temp2; + cmpOperator = SSE2_CMP_OP(cond, false); } else { if (!result.similar(lhsCmp)) { - EMIT(CPOS(s, MIR_Move.create(single ? IA32_MOVSS : IA32_MOVSD, result.copyRO(), lhsCmp))); + EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_MOVSS : IA32_MOVSD, result.copyRO(), lhsCmp))); } } EMIT(MIR_BinaryAcc.mutate(s, cmpOperator, result, rhsCmp)); // result contains all 1s or 0s, use masks and OR to perform conditional move - EMIT(CPOS(s, MIR_Move.create(single ? IA32_ANDPS : IA32_ANDPD, temp.copyRO(), result.copyRO()))); - EMIT(CPOS(s, MIR_Move.create(single ? IA32_ANDNPS : IA32_ANDNPD, result.copyRO(), falseValue))); - EMIT(CPOS(s, MIR_Move.create(single ? IA32_ORPS : IA32_ORPD, result.copyRO(), temp.copyRO()))); + EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_ANDPS : IA32_ANDPD, temp.copyRO(), result.copyRO()))); + EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_ANDNPS : IA32_ANDNPD, result.copyRO(), falseValue))); + EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_ORPS : IA32_ORPD, result.copyRO(), temp.copyRO()))); } protected final boolean IS_MATERIALIZE_ZERO(Instruction s) { Modified: rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2009-01-01 18:46:38 UTC (rev 15246) +++ rvmroot/trunk/rvm/src-generated/opt-burs/ia32/IA32_SSE2.rules 2009-01-01 23:41:31 UTC (rev 15247) @@ -448,14 +448,81 @@ CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); +r: FCMP_CMOV(r, OTHER_OPERAND(float_load, any)) +13+15 +EMIT_INSTRUCTION +EMIT(CPOS(P(p), MIR_Compare.create(IA32_UCOMISS, CondMove.getVal1(P(p)), consumeMO()))); \ +CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ + CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); + +r: FCMP_CMOV(r, OTHER_OPERAND(double_load, any)) +13+15 +EMIT_INSTRUCTION +EMIT(CPOS(P(p), MIR_Compare.create(IA32_UCOMISD, CondMove.getVal1(P(p)), consumeMO()))); \ +CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ + CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); + +r: FCMP_CMOV(float_load, OTHER_OPERAND(r, any)) +13+15 +EMIT_INSTRUCTION +CondMove.getCond(P(p)).flipOperands(); \ +EMIT(CPOS(P(p), MIR_Compare.create(IA32_UCOMISS, CondMove.getVal1(P(p)), consumeMO()))); \ +CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ + CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); + +r: FCMP_CMOV(double_load, OTHER_OPERAND(r, any)) +13+15 +EMIT_INSTRUCTION +CondMove.getCond(P(p)).flipOperands(); \ +EMIT(CPOS(P(p), MIR_Compare.create(IA32_UCOMISD, CondMove.getVal1(P(p)), consumeMO()))); \ +CMOV_MOV(P(p), CondMove.getResult(P(p)), CondMove.getCond(P(p)).translateUNSIGNED(), \ + CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); + ##### # FCMP_FCMOV ##### r: FCMP_FCMOV(r, OTHER_OPERAND(r, any)) 13*4 EMIT_INSTRUCTION -SSE2_FCMP_FCMOV(P(p)); +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), CondMove.getVal2(P(p)), \ + CondMove.getCond(P(p)), CondMove.getTrueValue(P(p)), CondMove.getFalseValue(P(p))); +r: FCMP_FCMOV(r, OTHER_OPERAND(r, OTHER_OPERAND(r, float_load))) +15+13*3 +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), CondMove.getVal2(P(p)), \ + CondMove.getCond(P(p)), CondMove.getTrueValue(P(p)), consumeMO()); + +r: FCMP_FCMOV(r, OTHER_OPERAND(r, OTHER_OPERAND(r, double_load))) +15+13*3 +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), CondMove.getVal2(P(p)), \ + CondMove.getCond(P(p)), CondMove.getTrueValue(P(p)), consumeMO()); + +r: FCMP_FCMOV(r, OTHER_OPERAND(r, OTHER_OPERAND(float_load, r))) +15+13*3 +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), CondMove.getVal2(P(p)), \ + CondMove.getCond(P(p)), consumeMO(), CondMove.getFalseValue(P(p))); + +r: FCMP_FCMOV(r, OTHER_OPERAND(r, OTHER_OPERAND(double_load, r))) +15+13*3 +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), CondMove.getVal2(P(p)), \ + CondMove.getCond(P(p)), consumeMO(), CondMove.getFalseValue(P(p))); + +r: FCMP_FCMOV(r, OTHER_OPERAND(float_load, any)) +SSE2_CMP_OP(CondMove.getCond(P(p)), true) != null ? 15+13*3 : INFINITE +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), consumeMO(), \ + CondMove.getCond(P(p)), CondMove.getFalseValue(P(p)), CondMove.getTrueValue(P(p))); + +r: FCMP_FCMOV(r, OTHER_OPERAND(double_load, any)) +SSE2_CMP_OP(CondMove.getCond(P(p)), false) != null ? 15+13*3 : INFINITE +EMIT_INSTRUCTION +SSE2_FCMP_FCMOV(P(p), CondMove.getResult(P(p)), CondMove.getVal1(P(p)), consumeMO(), \ + CondMove.getCond(P(p)), CondMove.getFalseValue(P(p)), CondMove.getTrueValue(P(p))); + ##### # Absolute ##### This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |