< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantLoadOptimization.java

Print this page
rev 52509 : [mq]: graal2


  48 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
  49 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
  50 import org.graalvm.compiler.lir.ValueConsumer;
  51 import org.graalvm.compiler.lir.Variable;
  52 import org.graalvm.compiler.lir.constopt.ConstantTree.Flags;
  53 import org.graalvm.compiler.lir.constopt.ConstantTree.NodeCost;
  54 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  55 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  56 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
  57 import org.graalvm.compiler.options.NestedBooleanOptionKey;
  58 import org.graalvm.compiler.options.Option;
  59 import org.graalvm.compiler.options.OptionType;
  60 
  61 import jdk.vm.ci.code.TargetDescription;
  62 import jdk.vm.ci.meta.Constant;
  63 import jdk.vm.ci.meta.Value;
  64 import jdk.vm.ci.meta.ValueKind;
  65 
  66 /**
  67  * This optimization tries to improve the handling of constants by replacing a single definition of
  68  * a constant, which is potentially scheduled into a block with high probability, with one or more
  69  * definitions in blocks with a lower probability.
  70  */
  71 public final class ConstantLoadOptimization extends PreAllocationOptimizationPhase {
  72 
  73     public static class Options {
  74         // @formatter:off
  75         @Option(help = "Enable constant load optimization.", type = OptionType.Debug)
  76         public static final NestedBooleanOptionKey LIROptConstantLoadOptimization = new NestedBooleanOptionKey(LIROptimization, true);
  77         // @formatter:on
  78     }
  79 
  80     @Override
  81     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) {
  82         LIRGeneratorTool lirGen = context.lirGen;
  83         new Optimization(lirGenRes.getLIR(), lirGen).apply();
  84     }
  85 
  86     private static final CounterKey constantsTotal = DebugContext.counter("ConstantLoadOptimization[total]");
  87     private static final CounterKey phiConstantsSkipped = DebugContext.counter("ConstantLoadOptimization[PhisSkipped]");
  88     private static final CounterKey singleUsageConstantsSkipped = DebugContext.counter("ConstantLoadOptimization[SingleUsageSkipped]");
  89     private static final CounterKey usageAtDefinitionSkipped = DebugContext.counter("ConstantLoadOptimization[UsageAtDefinitionSkipped]");


 254          */
 255         @SuppressWarnings("try")
 256         private void createConstantTree(DefUseTree tree) {
 257             ConstantTree constTree = new ConstantTree(lir.getControlFlowGraph(), tree);
 258             constTree.set(Flags.SUBTREE, tree.getBlock());
 259             tree.forEach(u -> constTree.set(Flags.USAGE, u.getBlock()));
 260 
 261             if (constTree.get(Flags.USAGE, tree.getBlock())) {
 262                 // usage in the definition block -> no optimization
 263                 usageAtDefinitionSkipped.increment(debug);
 264                 return;
 265             }
 266 
 267             constTree.markBlocks();
 268 
 269             NodeCost cost = ConstantTreeAnalyzer.analyze(debug, constTree, tree.getBlock());
 270             int usageCount = cost.getUsages().size();
 271             assert usageCount == tree.usageCount() : "Usage count differs: " + usageCount + " vs. " + tree.usageCount();
 272 
 273             if (debug.isLogEnabled()) {
 274                 try (Indent i = debug.logAndIndent("Variable: %s, Block: %s, prob.: %f", tree.getVariable(), tree.getBlock(), tree.getBlock().probability())) {
 275                     debug.log("Usages result: %s", cost);
 276                 }
 277 
 278             }
 279 
 280             if (cost.getNumMaterializations() > 1 || cost.getBestCost() < tree.getBlock().probability()) {
 281                 try (DebugContext.Scope s = debug.scope("CLOmodify", constTree); Indent i = debug.logAndIndent("Replacing %s = %s", tree.getVariable(), tree.getConstant().toValueString())) {
 282                     // mark original load for removal
 283                     deleteInstruction(tree);
 284                     constantsOptimized.increment(debug);
 285 
 286                     // collect result
 287                     createLoads(tree, constTree, tree.getBlock());
 288 
 289                 } catch (Throwable e) {
 290                     throw debug.handle(e);
 291                 }
 292             } else {
 293                 // no better solution found
 294                 materializeAtDefinitionSkipped.increment(debug);
 295             }
 296             debug.dump(DebugContext.DETAILED_LEVEL, constTree, "ConstantTree for %s", tree.getVariable());
 297         }
 298 
 299         private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlockBase<?> startBlock) {
 300             Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>();




  48 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
  49 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
  50 import org.graalvm.compiler.lir.ValueConsumer;
  51 import org.graalvm.compiler.lir.Variable;
  52 import org.graalvm.compiler.lir.constopt.ConstantTree.Flags;
  53 import org.graalvm.compiler.lir.constopt.ConstantTree.NodeCost;
  54 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  55 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  56 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
  57 import org.graalvm.compiler.options.NestedBooleanOptionKey;
  58 import org.graalvm.compiler.options.Option;
  59 import org.graalvm.compiler.options.OptionType;
  60 
  61 import jdk.vm.ci.code.TargetDescription;
  62 import jdk.vm.ci.meta.Constant;
  63 import jdk.vm.ci.meta.Value;
  64 import jdk.vm.ci.meta.ValueKind;
  65 
  66 /**
  67  * This optimization tries to improve the handling of constants by replacing a single definition of
  68  * a constant, which is potentially scheduled into a block with high frequency, with one or more
  69  * definitions in blocks with a lower frequency.
  70  */
  71 public final class ConstantLoadOptimization extends PreAllocationOptimizationPhase {
  72 
  73     public static class Options {
  74         // @formatter:off
  75         @Option(help = "Enable constant load optimization.", type = OptionType.Debug)
  76         public static final NestedBooleanOptionKey LIROptConstantLoadOptimization = new NestedBooleanOptionKey(LIROptimization, true);
  77         // @formatter:on
  78     }
  79 
  80     @Override
  81     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) {
  82         LIRGeneratorTool lirGen = context.lirGen;
  83         new Optimization(lirGenRes.getLIR(), lirGen).apply();
  84     }
  85 
  86     private static final CounterKey constantsTotal = DebugContext.counter("ConstantLoadOptimization[total]");
  87     private static final CounterKey phiConstantsSkipped = DebugContext.counter("ConstantLoadOptimization[PhisSkipped]");
  88     private static final CounterKey singleUsageConstantsSkipped = DebugContext.counter("ConstantLoadOptimization[SingleUsageSkipped]");
  89     private static final CounterKey usageAtDefinitionSkipped = DebugContext.counter("ConstantLoadOptimization[UsageAtDefinitionSkipped]");


 254          */
 255         @SuppressWarnings("try")
 256         private void createConstantTree(DefUseTree tree) {
 257             ConstantTree constTree = new ConstantTree(lir.getControlFlowGraph(), tree);
 258             constTree.set(Flags.SUBTREE, tree.getBlock());
 259             tree.forEach(u -> constTree.set(Flags.USAGE, u.getBlock()));
 260 
 261             if (constTree.get(Flags.USAGE, tree.getBlock())) {
 262                 // usage in the definition block -> no optimization
 263                 usageAtDefinitionSkipped.increment(debug);
 264                 return;
 265             }
 266 
 267             constTree.markBlocks();
 268 
 269             NodeCost cost = ConstantTreeAnalyzer.analyze(debug, constTree, tree.getBlock());
 270             int usageCount = cost.getUsages().size();
 271             assert usageCount == tree.usageCount() : "Usage count differs: " + usageCount + " vs. " + tree.usageCount();
 272 
 273             if (debug.isLogEnabled()) {
 274                 try (Indent i = debug.logAndIndent("Variable: %s, Block: %s, freq.: %f", tree.getVariable(), tree.getBlock(), tree.getBlock().getRelativeFrequency())) {
 275                     debug.log("Usages result: %s", cost);
 276                 }
 277 
 278             }
 279 
 280             if (cost.getNumMaterializations() > 1 || cost.getBestCost() < tree.getBlock().getRelativeFrequency()) {
 281                 try (DebugContext.Scope s = debug.scope("CLOmodify", constTree); Indent i = debug.logAndIndent("Replacing %s = %s", tree.getVariable(), tree.getConstant().toValueString())) {
 282                     // mark original load for removal
 283                     deleteInstruction(tree);
 284                     constantsOptimized.increment(debug);
 285 
 286                     // collect result
 287                     createLoads(tree, constTree, tree.getBlock());
 288 
 289                 } catch (Throwable e) {
 290                     throw debug.handle(e);
 291                 }
 292             } else {
 293                 // no better solution found
 294                 materializeAtDefinitionSkipped.increment(debug);
 295             }
 296             debug.dump(DebugContext.DETAILED_LEVEL, constTree, "ConstantTree for %s", tree.getVariable());
 297         }
 298 
 299         private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlockBase<?> startBlock) {
 300             Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>();


< prev index next >