< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -36,32 +36,34 @@
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.asm.AbstractAddress;
 import org.graalvm.compiler.asm.Assembler;
+import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
 import org.graalvm.compiler.code.DataSection.Data;
 import org.graalvm.compiler.code.DataSection.RawData;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
-import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.lir.LIR;
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.LIRInstruction;
 import org.graalvm.compiler.lir.LabelRef;
+import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp;
 import org.graalvm.compiler.lir.framemap.FrameMap;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 
+import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.CodeCacheProvider;
 import jdk.vm.ci.code.DebugInfo;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;

@@ -153,10 +155,24 @@
     private final EconomicMap<Constant, Data> dataCache;
 
     private Consumer<LIRInstruction> beforeOp;
     private Consumer<LIRInstruction> afterOp;
 
+    /**
+     * These position maps are used for estimating offsets of forward branches. Used for
+     * architectures where certain branch instructions have limited displacement such as ARM tbz or
+     * SPARC cbcond.
+     */
+    private EconomicMap<Label, Integer> labelBindLirPositions;
+    private EconomicMap<LIRInstruction, Integer> lirPositions;
+    /**
+     * This flag is for setting the
+     * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} into a
+     * conservative mode and always answering false.
+     */
+    private boolean conservativeLabelOffsets = false;
+
     public final boolean mustReplaceWithNullRegister(JavaConstant nullConstant) {
         return !nullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant);
     }
 
     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext,

@@ -177,18 +193,10 @@
         this.frameContext = frameContext;
         this.options = options;
         this.debug = debug;
         assert frameContext != null;
         this.dataCache = dataCache;
-
-        if (dataBuilder.needDetailedPatchingInformation() || Assertions.assertionsEnabled()) {
-            /*
-             * Always enabled in debug mode, even when the VM does not request detailed information,
-             * to increase test coverage.
-             */
-            asm.setCodePatchingAnnotationConsumer(assemblerCodeAnnotation -> compilationResult.addAnnotation(new AssemblerAnnotation(assemblerCodeAnnotation)));
-        }
     }
 
     public void setTotalFrameSize(int frameSize) {
         compilationResult.setTotalFrameSize(frameSize);
     }

@@ -541,10 +549,12 @@
             int start = crb.asm.position();
             op.emitCode(crb);
             if (op.getPosition() != null) {
                 crb.recordSourceMapping(start, crb.asm.position(), op.getPosition());
             }
+        } catch (BailoutException e) {
+            throw e;
         } catch (AssertionError t) {
             throw new GraalError(t);
         } catch (RuntimeException t) {
             throw new GraalError(t);
         }

@@ -557,10 +567,12 @@
             exceptionInfoList.clear();
         }
         if (dataCache != null) {
             dataCache.clear();
         }
+        lir = null;
+        currentBlockIndex = 0;
     }
 
     public void setOpCallback(Consumer<LIRInstruction> beforeOp, Consumer<LIRInstruction> afterOp) {
         this.beforeOp = beforeOp;
         this.afterOp = afterOp;

@@ -568,6 +580,59 @@
 
     public OptionValues getOptions() {
         return options;
     }
 
+    /**
+     * Builds up a map for label and LIR instruction positions where labels are or labels pointing
+     * to.
+     */
+    public void buildLabelOffsets(LIR generatedLIR) {
+        labelBindLirPositions = EconomicMap.create(Equivalence.IDENTITY);
+        lirPositions = EconomicMap.create(Equivalence.IDENTITY);
+        int instructionPosition = 0;
+        for (AbstractBlockBase<?> block : generatedLIR.codeEmittingOrder()) {
+            if (block != null) {
+                for (LIRInstruction op : generatedLIR.getLIRforBlock(block)) {
+                    if (op instanceof LabelHoldingOp) {
+                        Label label = ((LabelHoldingOp) op).getLabel();
+                        if (label != null) {
+                            labelBindLirPositions.put(label, instructionPosition);
+                        }
+                        lirPositions.put(op, instructionPosition);
+                    }
+                    instructionPosition++;
+                }
+            }
+        }
+    }
+
+    /**
+     * Answers the code generator whether the jump from instruction to label is within disp LIR
+     * instructions.
+     *
+     * @param disp Maximum number of LIR instructions between label and instruction
+     */
+    public boolean labelWithinRange(LIRInstruction instruction, Label label, int disp) {
+        if (conservativeLabelOffsets) {
+            return false;
+        }
+        Integer labelPosition = labelBindLirPositions.get(label);
+        Integer instructionPosition = lirPositions.get(instruction);
+        boolean result;
+        if (labelPosition != null && instructionPosition != null) {
+            result = Math.abs(labelPosition - instructionPosition) < disp;
+        } else {
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     * Sets this CompilationResultBuilder into conservative mode. If set,
+     * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} always returns
+     * false.
+     */
+    public void setConservativeLabelRanges() {
+        this.conservativeLabelOffsets = true;
+    }
 }
< prev index next >