8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25
26 package org.graalvm.compiler.core.amd64;
27
28 import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks;
29
30 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
31 import org.graalvm.compiler.debug.GraalError;
32 import org.graalvm.compiler.lir.LIRFrameState;
33 import org.graalvm.compiler.lir.amd64.AMD64Call;
34 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
35 import org.graalvm.compiler.nodes.DeoptimizingNode;
36 import org.graalvm.compiler.nodes.FixedNode;
37 import org.graalvm.compiler.nodes.FixedWithNextNode;
38 import org.graalvm.compiler.nodes.IfNode;
39 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
40 import org.graalvm.compiler.nodes.StructuredGraph;
41 import org.graalvm.compiler.nodes.ValueNode;
42 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
43 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
44 import org.graalvm.compiler.nodes.cfg.Block;
45 import org.graalvm.compiler.options.Option;
46 import org.graalvm.compiler.options.OptionKey;
47 import org.graalvm.compiler.options.OptionType;
48 import org.graalvm.compiler.options.OptionValues;
49
50 import jdk.vm.ci.amd64.AMD64;
51 import jdk.vm.ci.meta.AllocatableValue;
52 import jdk.vm.ci.meta.Value;
53
54 public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
55
56 public static class Options {
57 // @formatter:off
58 @Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert)
59 public static final OptionKey<Boolean> MitigateSpeculativeExecutionAttacks = new OptionKey<>(false);
60 // @formatter:on
61 }
62
63 public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
64 super(graph, gen, nodeMatchRules);
65 }
66
67 @Override
68 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
69 Value targetAddressSrc = operand(callTarget.computedAddress());
70 AllocatableValue targetAddress = AMD64.rax.asValue(targetAddressSrc.getValueKind());
71 gen.emitMove(targetAddress, targetAddressSrc);
72 append(new AMD64Call.IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, targetAddress, callState));
73 }
74
75 @Override
76 protected boolean peephole(ValueNode valueNode) {
77 if (valueNode instanceof IntegerDivRemNode) {
78 AMD64ArithmeticLIRGenerator arithmeticGen = (AMD64ArithmeticLIRGenerator) gen.getArithmetic();
79 IntegerDivRemNode divRem = (IntegerDivRemNode) valueNode;
80 FixedNode node = divRem.next();
81 while (true) {
82 if (node instanceof IfNode) {
119 assert otherDivRem.getOp() == Op.DIV;
120 setResult(divRem, results[1]);
121 setResult(otherDivRem, results[0]);
122 break;
123 default:
124 throw GraalError.shouldNotReachHere();
125 }
126 return true;
127 }
128 }
129 }
130 node = fixedWithNextNode.next();
131 }
132 }
133 return false;
134 }
135
136 @Override
137 public AMD64LIRGenerator getLIRGeneratorTool() {
138 return (AMD64LIRGenerator) gen;
139 }
140
141 @Override
142 public void doBlockPrologue(Block block, OptionValues options) {
143 if (MitigateSpeculativeExecutionAttacks.getValue(options)) {
144 boolean hasControlSplitPredecessor = false;
145 for (Block b : block.getPredecessors()) {
146 if (b.getSuccessorCount() > 1) {
147 hasControlSplitPredecessor = true;
148 break;
149 }
150 }
151 boolean isStartBlock = block.getPredecessorCount() == 0;
152 if (hasControlSplitPredecessor || isStartBlock) {
153 getLIRGeneratorTool().emitLFence();
154 }
155 }
156 }
157 }
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25
26 package org.graalvm.compiler.core.amd64;
27
28 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
29 import org.graalvm.compiler.debug.GraalError;
30 import org.graalvm.compiler.lir.LIRFrameState;
31 import org.graalvm.compiler.lir.amd64.AMD64Call;
32 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
33 import org.graalvm.compiler.nodes.DeoptimizingNode;
34 import org.graalvm.compiler.nodes.FixedNode;
35 import org.graalvm.compiler.nodes.FixedWithNextNode;
36 import org.graalvm.compiler.nodes.IfNode;
37 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
38 import org.graalvm.compiler.nodes.StructuredGraph;
39 import org.graalvm.compiler.nodes.ValueNode;
40 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
41 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
42
43 import jdk.vm.ci.amd64.AMD64;
44 import jdk.vm.ci.meta.AllocatableValue;
45 import jdk.vm.ci.meta.Value;
46
47 public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
48
49 public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
50 super(graph, gen, nodeMatchRules);
51 }
52
53 @Override
54 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
55 Value targetAddressSrc = operand(callTarget.computedAddress());
56 AllocatableValue targetAddress = AMD64.rax.asValue(targetAddressSrc.getValueKind());
57 gen.emitMove(targetAddress, targetAddressSrc);
58 append(new AMD64Call.IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, targetAddress, callState));
59 }
60
61 @Override
62 protected boolean peephole(ValueNode valueNode) {
63 if (valueNode instanceof IntegerDivRemNode) {
64 AMD64ArithmeticLIRGenerator arithmeticGen = (AMD64ArithmeticLIRGenerator) gen.getArithmetic();
65 IntegerDivRemNode divRem = (IntegerDivRemNode) valueNode;
66 FixedNode node = divRem.next();
67 while (true) {
68 if (node instanceof IfNode) {
105 assert otherDivRem.getOp() == Op.DIV;
106 setResult(divRem, results[1]);
107 setResult(otherDivRem, results[0]);
108 break;
109 default:
110 throw GraalError.shouldNotReachHere();
111 }
112 return true;
113 }
114 }
115 }
116 node = fixedWithNextNode.next();
117 }
118 }
119 return false;
120 }
121
122 @Override
123 public AMD64LIRGenerator getLIRGeneratorTool() {
124 return (AMD64LIRGenerator) gen;
125 }
126 }
|