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 org.jikesrvm.adaptive.controller.Controller;
017 import org.jikesrvm.adaptive.measurements.instrumentation.Instrumentation;
018 import org.jikesrvm.adaptive.util.AOSOptions;
019 import org.jikesrvm.compilers.opt.InstrumentedEventCounterManager;
020 import org.jikesrvm.compilers.opt.OptOptions;
021 import org.jikesrvm.compilers.opt.driver.CompilerPhase;
022 import org.jikesrvm.compilers.opt.ir.BasicBlock;
023 import org.jikesrvm.compilers.opt.ir.BasicBlockEnumeration;
024 import org.jikesrvm.compilers.opt.ir.IR;
025 import org.jikesrvm.compilers.opt.ir.Instruction;
026 import static org.jikesrvm.compilers.opt.ir.Operators.INSTRUMENTED_EVENT_COUNTER;
027
028 /**
029 * This phase takes converts "instrumentation instructions" that were
030 * inserted by previous instrumentation phases and "lowers" them,
031 * converting them to the actual instructions that perform the
032 * instrumentation.
033 */
034 public class LowerInstrumentation extends CompilerPhase {
035
036 static final boolean DEBUG = false;
037
038 /**
039 * Return this instance of this phase. This phase contains no
040 * per-compilation instance fields.
041 * @param ir not used
042 * @return this
043 */
044 public CompilerPhase newExecution(IR ir) {
045 return this;
046 }
047
048 public final boolean shouldPerform(OptOptions options) {
049 AOSOptions opts = Controller.options;
050 return opts
051 .INSERT_INSTRUCTION_COUNTERS ||
052 opts
053 .INSERT_METHOD_COUNTERS_OPT ||
054 opts
055 .INSERT_DEBUGGING_COUNTERS ||
056 opts
057 .INSERT_YIELDPOINT_COUNTERS;
058 }
059
060 public final String getName() { return "LowerInstrumentation"; }
061
062 /**
063 * Finds all instrumented instructions and calls the appropriate code to
064 * convert it into the real sequence of instrumentation instructions.
065 *
066 * @param ir the governing IR
067 */
068 public final void perform(IR ir) {
069 // Convert all instrumentation instructions into actual counter code
070 lowerInstrumentation(ir);
071
072 // TODO: For efficiency, should proably call Simple, or
073 // branch optimizations or something.
074 }
075
076 /**
077 * Actually perform the lowering
078 *
079 * @param ir the governing IR
080 */
081 static void lowerInstrumentation(IR ir) {
082 /*
083 for (BasicBlockEnumeration bbe = ir.getBasicBlocks();
084 bbe.hasMoreElements(); ) {
085 BasicBlock bb = bbe.next();
086 bb.printExtended();
087 }
088 */
089
090 ArrayList<Instruction> instrumentedInstructions = new ArrayList<Instruction>();
091
092 // Go through all instructions and find the instrumented ones. We
093 // put them in instrumentedInstructions and expand them later
094 // because if we expanded them on the fly we mess up the
095 // enumeration.
096 for (BasicBlockEnumeration bbe = ir.getBasicBlocks(); bbe.hasMoreElements();) {
097 BasicBlock bb = bbe.next();
098
099 Instruction i = bb.firstInstruction();
100 while (i != null && i != bb.lastInstruction()) {
101
102 if (i.operator() == INSTRUMENTED_EVENT_COUNTER) {
103 instrumentedInstructions.add(i);
104 }
105 i = i.nextInstructionInCodeOrder();
106 }
107 }
108
109 // Now go through the instructions and "lower" them by calling
110 // the counter manager to convert them into real instructions
111 for (final Instruction i : instrumentedInstructions) {
112 // Have the counter manager for this data convert this into the
113 // actual counting code. For now, we'll hard code the counter
114 // manager. Ideally it should be stored in the instruction,
115 // (to allow multiple counter managers. It would also make this
116 // code independant of the adaptive system..)
117 InstrumentedEventCounterManager counterManager = Instrumentation.eventCounterManager;
118
119 counterManager.mutateOptEventCounterInstruction(i, ir);
120 }
121
122 /*
123 for (BasicBlockEnumeration bbe = ir.getBasicBlocks();
124 bbe.hasMoreElements(); ) {
125 BasicBlock bb = bbe.next();
126 bb.printExtended();
127 }
128 */
129 } // end of lowerInstrumentation
130
131 }