001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.adaptive.recompilation.instrumentation; 014 015 import java.util.ArrayList; 016 import java.util.Enumeration; 017 018 import org.jikesrvm.adaptive.controller.Controller; 019 import org.jikesrvm.adaptive.measurements.instrumentation.Instrumentation; 020 import org.jikesrvm.adaptive.util.AOSOptions; 021 import org.jikesrvm.compilers.opt.InstrumentedEventCounterManager; 022 import org.jikesrvm.compilers.opt.OptOptions; 023 import org.jikesrvm.compilers.opt.driver.CompilerPhase; 024 import org.jikesrvm.compilers.opt.ir.BasicBlock; 025 import org.jikesrvm.compilers.opt.ir.IR; 026 import org.jikesrvm.compilers.opt.ir.Instruction; 027 import static org.jikesrvm.compilers.opt.ir.Operators.INSTRUMENTED_EVENT_COUNTER; 028 029 /** 030 * This phase takes converts "instrumentation instructions" that were 031 * inserted by previous instrumentation phases and "lowers" them, 032 * converting them to the actual instructions that perform the 033 * instrumentation. 034 */ 035 public class LowerInstrumentation extends CompilerPhase { 036 037 static final boolean DEBUG = false; 038 039 /** 040 * Return this instance of this phase. This phase contains no 041 * per-compilation instance fields. 042 * @param ir not used 043 * @return this 044 */ 045 @Override 046 public CompilerPhase newExecution(IR ir) { 047 return this; 048 } 049 050 @Override 051 public final boolean shouldPerform(OptOptions options) { 052 AOSOptions opts = Controller.options; 053 return opts 054 .INSERT_INSTRUCTION_COUNTERS || 055 opts 056 .INSERT_METHOD_COUNTERS_OPT || 057 opts 058 .INSERT_DEBUGGING_COUNTERS || 059 opts 060 .INSERT_YIELDPOINT_COUNTERS; 061 } 062 063 @Override 064 public final String getName() { return "LowerInstrumentation"; } 065 066 /** 067 * Finds all instrumented instructions and calls the appropriate code to 068 * convert it into the real sequence of instrumentation instructions. 069 * 070 * @param ir the governing IR 071 */ 072 @Override 073 public final void perform(IR ir) { 074 // Convert all instrumentation instructions into actual counter code 075 lowerInstrumentation(ir); 076 077 // TODO: For efficiency, should probably call Simple, or 078 // branch optimizations or something. 079 } 080 081 /** 082 * Actually perform the lowering 083 * 084 * @param ir the governing IR 085 */ 086 static void lowerInstrumentation(IR ir) { 087 /* 088 for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); 089 bbe.hasMoreElements(); ) { 090 BasicBlock bb = bbe.nextElement(); 091 bb.printExtended(); 092 } 093 */ 094 095 ArrayList<Instruction> instrumentedInstructions = new ArrayList<Instruction>(); 096 097 // Go through all instructions and find the instrumented ones. We 098 // put them in instrumentedInstructions and expand them later 099 // because if we expanded them on the fly we mess up the 100 // enumeration. 101 for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements();) { 102 BasicBlock bb = bbe.nextElement(); 103 104 Instruction i = bb.firstInstruction(); 105 while (i != null && i != bb.lastInstruction()) { 106 107 if (i.operator() == INSTRUMENTED_EVENT_COUNTER) { 108 instrumentedInstructions.add(i); 109 } 110 i = i.nextInstructionInCodeOrder(); 111 } 112 } 113 114 // Now go through the instructions and "lower" them by calling 115 // the counter manager to convert them into real instructions 116 for (final Instruction i : instrumentedInstructions) { 117 // Have the counter manager for this data convert this into the 118 // actual counting code. For now, we'll hard code the counter 119 // manager. Ideally it should be stored in the instruction, 120 // (to allow multiple counter managers. It would also make this 121 // code independent of the adaptive system..) 122 InstrumentedEventCounterManager counterManager = Instrumentation.eventCounterManager; 123 124 counterManager.mutateOptEventCounterInstruction(i, ir); 125 } 126 127 /* 128 for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); 129 bbe.hasMoreElements(); ) { 130 BasicBlock bb = bbe.nextElement(); 131 bb.printExtended(); 132 } 133 */ 134 } // end of lowerInstrumentation 135 136 }