changeset 48065:25cfedf27edc

8192814: Update Graal Reviewed-by: kvn
author dlong
date Fri, 01 Dec 2017 11:17:45 -0800
parents acffbbe79871
children d8a62bea95d3
files src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AllocatorTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCAddressLowering.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCImmediateAddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIndexedAddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIntegerCompareCanonicalizationPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UncheckedInterfaceProviderTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeUnsafeStoreTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/VersionsTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Versions.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/DataPatchInConstantsTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvokeDynamicPlugin.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotCompressionNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/PointerCastNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/jdk/Unsafe_compareAndSwapNullCheck.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantTree.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/BasicInductionVariable.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedConvertedInductionVariable.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedOffsetInductionVariable.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedScaledInductionVariable.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/InductionVariable.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo.processor/src/org/graalvm/compiler/nodeinfo/processor/GraphNodeProcessor.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/NegateNodeCanonicalizationTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampDoubleToLongTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampFloatToIntTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampIntToFloatTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampLongToDoubleTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryProxyNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardedValueNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NodeView.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedDivNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRemNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/BlackholeNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/OpaqueNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GetClassNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/RawAddressNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/StampTool.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/EnsureVirtualizedNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NonNullParametersPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/InferStamps.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyUsageWithEquals.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyVirtualizableUsage.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64RoundNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MonitorTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SystemArrayCopyTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReverseBytesNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulHighNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java
diffstat 253 files changed, 4411 insertions(+), 1708 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Fri Dec 01 11:17:45 2017 -0800
@@ -352,17 +352,18 @@
      */
     private enum OpAssertion {
         ByteAssertion(CPU, CPU, BYTE),
-        IntegerAssertion(CPU, CPU, WORD, DWORD, QWORD),
-        No16BitAssertion(CPU, CPU, DWORD, QWORD),
-        No32BitAssertion(CPU, CPU, WORD, QWORD),
-        QwordOnlyAssertion(CPU, CPU, QWORD),
-        FloatingAssertion(XMM, XMM, SS, SD, PS, PD),
-        PackedFloatingAssertion(XMM, XMM, PS, PD),
+        ByteOrLargerAssertion(CPU, CPU, BYTE, WORD, DWORD, QWORD),
+        WordOrLargerAssertion(CPU, CPU, WORD, DWORD, QWORD),
+        DwordOrLargerAssertion(CPU, CPU, DWORD, QWORD),
+        WordOrDwordAssertion(CPU, CPU, WORD, QWORD),
+        QwordAssertion(CPU, CPU, QWORD),
+        FloatAssertion(XMM, XMM, SS, SD, PS, PD),
+        PackedFloatAssertion(XMM, XMM, PS, PD),
         SingleAssertion(XMM, XMM, SS),
         DoubleAssertion(XMM, XMM, SD),
         PackedDoubleAssertion(XMM, XMM, PD),
-        IntToFloatingAssertion(XMM, CPU, DWORD, QWORD),
-        FloatingToIntAssertion(CPU, XMM, DWORD, QWORD);
+        IntToFloatAssertion(XMM, CPU, DWORD, QWORD),
+        FloatToIntAssertion(CPU, XMM, DWORD, QWORD);
 
         private final RegisterCategory resultCategory;
         private final RegisterCategory inputCategory;
@@ -772,25 +773,25 @@
      */
     public static class AMD64RMOp extends AMD64RROp {
         // @formatter:off
-        public static final AMD64RMOp IMUL   = new AMD64RMOp("IMUL",         P_0F, 0xAF);
+        public static final AMD64RMOp IMUL   = new AMD64RMOp("IMUL",         P_0F, 0xAF, OpAssertion.ByteOrLargerAssertion);
         public static final AMD64RMOp BSF    = new AMD64RMOp("BSF",          P_0F, 0xBC);
         public static final AMD64RMOp BSR    = new AMD64RMOp("BSR",          P_0F, 0xBD);
         public static final AMD64RMOp POPCNT = new AMD64RMOp("POPCNT", 0xF3, P_0F, 0xB8, CPUFeature.POPCNT);
         public static final AMD64RMOp TZCNT  = new AMD64RMOp("TZCNT",  0xF3, P_0F, 0xBC, CPUFeature.BMI1);
         public static final AMD64RMOp LZCNT  = new AMD64RMOp("LZCNT",  0xF3, P_0F, 0xBD, CPUFeature.LZCNT);
-        public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB",       P_0F, 0xB6, false, true, OpAssertion.IntegerAssertion);
-        public static final AMD64RMOp MOVZX  = new AMD64RMOp("MOVZX",        P_0F, 0xB7, OpAssertion.No16BitAssertion);
-        public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB",       P_0F, 0xBE, false, true, OpAssertion.IntegerAssertion);
-        public static final AMD64RMOp MOVSX  = new AMD64RMOp("MOVSX",        P_0F, 0xBF, OpAssertion.No16BitAssertion);
-        public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD",             0x63, OpAssertion.QwordOnlyAssertion);
+        public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB",       P_0F, 0xB6, false, true, OpAssertion.WordOrLargerAssertion);
+        public static final AMD64RMOp MOVZX  = new AMD64RMOp("MOVZX",        P_0F, 0xB7, OpAssertion.DwordOrLargerAssertion);
+        public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB",       P_0F, 0xBE, false, true, OpAssertion.WordOrLargerAssertion);
+        public static final AMD64RMOp MOVSX  = new AMD64RMOp("MOVSX",        P_0F, 0xBF, OpAssertion.DwordOrLargerAssertion);
+        public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD",             0x63, OpAssertion.QwordAssertion);
         public static final AMD64RMOp MOVB   = new AMD64RMOp("MOVB",               0x8A, OpAssertion.ByteAssertion);
         public static final AMD64RMOp MOV    = new AMD64RMOp("MOV",                0x8B);
 
         // MOVD/MOVQ and MOVSS/MOVSD are the same opcode, just with different operand size prefix
-        public static final AMD64RMOp MOVD   = new AMD64RMOp("MOVD",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64RMOp MOVQ   = new AMD64RMOp("MOVQ",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64RMOp MOVSS  = new AMD64RMOp("MOVSS",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
-        public static final AMD64RMOp MOVSD  = new AMD64RMOp("MOVSD",        P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64RMOp MOVD   = new AMD64RMOp("MOVD",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64RMOp MOVQ   = new AMD64RMOp("MOVQ",   0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64RMOp MOVSS  = new AMD64RMOp("MOVSS",        P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
+        public static final AMD64RMOp MOVSD  = new AMD64RMOp("MOVSD",        P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
 
         // TEST is documented as MR operation, but it's symmetric, and using it as RM operation is more convenient.
         public static final AMD64RMOp TESTB  = new AMD64RMOp("TEST",               0x84, OpAssertion.ByteAssertion);
@@ -822,7 +823,7 @@
         }
 
         protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
-            this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
+            this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
         }
 
         protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@@ -1014,7 +1015,7 @@
         }
 
         protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
-            this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
+            this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
         }
 
         protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@@ -1114,12 +1115,12 @@
 
         // MOVD and MOVQ are the same opcode, just with different operand size prefix
         // Note that as MR opcodes, they have reverse operand order, so the IntToFloatingAssertion must be used.
-        public static final AMD64MROp MOVD   = new AMD64MROp("MOVD",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
-        public static final AMD64MROp MOVQ   = new AMD64MROp("MOVQ",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
+        public static final AMD64MROp MOVD   = new AMD64MROp("MOVD",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
+        public static final AMD64MROp MOVQ   = new AMD64MROp("MOVQ",   0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
 
         // MOVSS and MOVSD are the same opcode, just with different operand size prefix
-        public static final AMD64MROp MOVSS  = new AMD64MROp("MOVSS",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
-        public static final AMD64MROp MOVSD  = new AMD64MROp("MOVSD",        P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
+        public static final AMD64MROp MOVSS  = new AMD64MROp("MOVSS",        P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
+        public static final AMD64MROp MOVSD  = new AMD64MROp("MOVSD",        P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
         // @formatter:on
 
         protected AMD64MROp(String opcode, int op) {
@@ -1131,7 +1132,7 @@
         }
 
         protected AMD64MROp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.IntegerAssertion);
+            this(opcode, prefix, op, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MROp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1279,7 +1280,7 @@
         public static final AMD64MOp INC  = new AMD64MOp("INC",  0xFF, 0);
         public static final AMD64MOp DEC  = new AMD64MOp("DEC",  0xFF, 1);
         public static final AMD64MOp PUSH = new AMD64MOp("PUSH", 0xFF, 6);
-        public static final AMD64MOp POP  = new AMD64MOp("POP",  0x8F, 0, OpAssertion.No32BitAssertion);
+        public static final AMD64MOp POP  = new AMD64MOp("POP",  0x8F, 0, OpAssertion.WordOrDwordAssertion);
         // @formatter:on
 
         private final int ext;
@@ -1289,7 +1290,7 @@
         }
 
         protected AMD64MOp(String opcode, int prefix, int op, int ext) {
-            this(opcode, prefix, op, ext, OpAssertion.IntegerAssertion);
+            this(opcode, prefix, op, ext, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MOp(String opcode, int op, int ext, OpAssertion assertion) {
@@ -1327,7 +1328,7 @@
         private final int ext;
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext) {
-            this(opcode, immIsByte, op, ext, OpAssertion.IntegerAssertion);
+            this(opcode, immIsByte, op, ext, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext, OpAssertion assertion) {
@@ -1369,7 +1370,7 @@
         // @formatter:on
 
         protected AMD64RMIOp(String opcode, boolean immIsByte, int op) {
-            this(opcode, immIsByte, 0, op, OpAssertion.IntegerAssertion);
+            this(opcode, immIsByte, 0, op, OpAssertion.WordOrLargerAssertion);
         }
 
         protected AMD64RMIOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion) {
@@ -1504,16 +1505,16 @@
 
     public static class SSEOp extends AMD64RMOp {
         // @formatter:off
-        public static final SSEOp CVTSI2SS  = new SSEOp("CVTSI2SS",  0xF3, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
-        public static final SSEOp CVTSI2SD  = new SSEOp("CVTSI2SS",  0xF2, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
-        public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
-        public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
-        public static final SSEOp UCOMIS    = new SSEOp("UCOMIS",          P_0F, 0x2E, OpAssertion.PackedFloatingAssertion);
+        public static final SSEOp CVTSI2SS  = new SSEOp("CVTSI2SS",  0xF3, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
+        public static final SSEOp CVTSI2SD  = new SSEOp("CVTSI2SS",  0xF2, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
+        public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
+        public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
+        public static final SSEOp UCOMIS    = new SSEOp("UCOMIS",          P_0F, 0x2E, OpAssertion.PackedFloatAssertion);
         public static final SSEOp SQRT      = new SSEOp("SQRT",            P_0F, 0x51);
-        public static final SSEOp AND       = new SSEOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp ANDN      = new SSEOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp OR        = new SSEOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
-        public static final SSEOp XOR       = new SSEOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
+        public static final SSEOp AND       = new SSEOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp ANDN      = new SSEOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp OR        = new SSEOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatAssertion);
+        public static final SSEOp XOR       = new SSEOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatAssertion);
         public static final SSEOp ADD       = new SSEOp("ADD",             P_0F, 0x58);
         public static final SSEOp MUL       = new SSEOp("MUL",             P_0F, 0x59);
         public static final SSEOp CVTSS2SD  = new SSEOp("CVTSS2SD",        P_0F, 0x5A, OpAssertion.SingleAssertion);
@@ -1525,7 +1526,7 @@
         // @formatter:on
 
         protected SSEOp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.FloatingAssertion);
+            this(opcode, prefix, op, OpAssertion.FloatAssertion);
         }
 
         protected SSEOp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1539,10 +1540,10 @@
 
     public static class AVXOp extends AMD64RRMOp {
         // @formatter:off
-        public static final AVXOp AND       = new AVXOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp ANDN      = new AVXOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp OR        = new AVXOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
-        public static final AVXOp XOR       = new AVXOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
+        public static final AVXOp AND       = new AVXOp("AND",             P_0F, 0x54, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp ANDN      = new AVXOp("ANDN",            P_0F, 0x55, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp OR        = new AVXOp("OR",              P_0F, 0x56, OpAssertion.PackedFloatAssertion);
+        public static final AVXOp XOR       = new AVXOp("XOR",             P_0F, 0x57, OpAssertion.PackedFloatAssertion);
         public static final AVXOp ADD       = new AVXOp("ADD",             P_0F, 0x58);
         public static final AVXOp MUL       = new AVXOp("MUL",             P_0F, 0x59);
         public static final AVXOp SUB       = new AVXOp("SUB",             P_0F, 0x5C);
@@ -1552,7 +1553,7 @@
         // @formatter:on
 
         protected AVXOp(String opcode, int prefix, int op) {
-            this(opcode, prefix, op, OpAssertion.FloatingAssertion);
+            this(opcode, prefix, op, OpAssertion.FloatAssertion);
         }
 
         protected AVXOp(String opcode, int prefix, int op, OpAssertion assertion) {
@@ -1595,10 +1596,10 @@
             byteMrOp = new AMD64MROp(opcode, 0, baseOp, OpAssertion.ByteAssertion);
             byteRmOp = new AMD64RMOp(opcode, 0, baseOp | 0x02, OpAssertion.ByteAssertion);
 
-            immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.IntegerAssertion);
-            immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.IntegerAssertion);
-            mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.IntegerAssertion);
-            rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.IntegerAssertion);
+            immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.WordOrLargerAssertion);
+            immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.WordOrLargerAssertion);
+            mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.WordOrLargerAssertion);
+            rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.WordOrLargerAssertion);
         }
 
         public AMD64MIOp getMIOpcode(OperandSize size, boolean sx) {
@@ -1647,9 +1648,9 @@
         public final AMD64MIOp miOp;
 
         private AMD64Shift(String opcode, int code) {
-            m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.IntegerAssertion);
-            mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.IntegerAssertion);
-            miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.IntegerAssertion);
+            m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.WordOrLargerAssertion);
+            mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.WordOrLargerAssertion);
+            miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.WordOrLargerAssertion);
         }
     }
 
@@ -1967,6 +1968,12 @@
         }
     }
 
+    public final void lead(Register dst, AMD64Address src) {
+        prefix(src, dst);
+        emitByte(0x8D);
+        emitOperandHelper(dst, src, 0);
+    }
+
     public final void leaq(Register dst, AMD64Address src) {
         prefixq(src, dst);
         emitByte(0x8D);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressLoweringByUse.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,8 +24,6 @@
 
 package org.graalvm.compiler.core.aarch64;
 
-import jdk.vm.ci.aarch64.AArch64Kind;
-import jdk.vm.ci.meta.JavaConstant;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
@@ -34,9 +32,11 @@
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
 
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.meta.JavaConstant;
+
 public class AArch64AddressLoweringByUse extends AddressLoweringByUsePhase.AddressLoweringByUse {
     private AArch64LIRKindTool kindtool;
 
@@ -46,9 +46,7 @@
 
     @Override
     public AddressNode lower(ValueNode use, Stamp stamp, AddressNode address) {
-        if (address instanceof RawAddressNode) {
-            return doLower(stamp, address.getBase(), null);
-        } else if (address instanceof OffsetAddressNode) {
+        if (address instanceof OffsetAddressNode) {
             OffsetAddressNode offsetAddress = (OffsetAddressNode) address;
             return doLower(stamp, offsetAddress.getBase(), offsetAddress.getOffset());
         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64AddressNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -88,7 +89,7 @@
             }
         }
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new AArch64AddressValue(kind, baseValue, indexValue, (int) displacement, scaleFactor, addressingMode));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.memory.Access;
 
 import jdk.vm.ci.aarch64.AArch64Kind;
@@ -45,7 +46,7 @@
     }
 
     protected AArch64Kind getMemoryKind(Access access) {
-        return (AArch64Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
+        return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AllocatorTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AllocatorTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,7 +44,7 @@
 
     @Test
     public void test1() {
-        testAllocation("test1snippet", 3, 1, 0);
+        testAllocation("test1snippet", 3, 0, 0);
     }
 
     public static long test1snippet(long x) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Fri Dec 01 11:17:45 2017 -0800
@@ -25,24 +25,23 @@
 
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
 import org.graalvm.compiler.nodes.calc.NegateNode;
-import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
 
 import jdk.vm.ci.meta.JavaConstant;
 
 public class AMD64AddressLowering extends AddressLowering {
-    @Override
-    public AddressNode lower(ValueNode address) {
-        return lower(address, null);
-    }
+    private static final int ADDRESS_BITS = 64;
 
     @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
@@ -54,9 +53,15 @@
             changed = improve(graph, base.getDebug(), ret, false, false);
         } while (changed);
 
+        assert checkAddressBitWidth(ret.getBase());
+        assert checkAddressBitWidth(ret.getIndex());
         return graph.unique(ret);
     }
 
+    private static boolean checkAddressBitWidth(ValueNode value) {
+        return value == null || value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(value.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
+    }
+
     /**
      * Tries to optimize addresses so that they match the AMD64-specific addressing mode better
      * (base + index * scale + displacement).
@@ -148,7 +153,7 @@
                 if (base == ret.getBase()) {
                     ret.setBase(originalBase);
                 } else if (ret.getBase() != null) {
-                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
+                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase(), NodeView.DEFAULT)));
                 }
             }
 
@@ -156,7 +161,7 @@
                 if (index == ret.getIndex()) {
                     ret.setIndex(originalIndex);
                 } else if (ret.getIndex() != null) {
-                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
+                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex(), NodeView.DEFAULT)));
                 }
             }
             return improved;
@@ -168,12 +173,12 @@
 
     private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
         if (negate && value != null) {
-            return graph.maybeAddOrUnique(NegateNode.create(value));
+            return graph.maybeAddOrUnique(NegateNode.create(value, NodeView.DEFAULT));
         }
         return value;
     }
 
-    private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
+    private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
         if (node == null) {
             return null;
         }
@@ -182,30 +187,26 @@
         if (c != null) {
             return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
         } else {
-            if (node.stamp() instanceof IntegerStamp) {
-                if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
-                    /*
-                     * we can't just swallow all zero-extends as we might encounter something like
-                     * the following: ZeroExtend(Add(negativeValue, positiveValue)).
-                     *
-                     * if we swallow the zero-extend in this case and subsequently optimize the add,
-                     * we might end up with a negative value that has less than 64 bits in base or
-                     * index. such a value would require sign extension instead of zero-extension
-                     * but the backend can only do zero-extension. if we ever want to optimize that
-                     * further, we would also need to be careful about over-/underflows.
-                     *
-                     * furthermore, we also can't swallow zero-extends with less than 32 bits as
-                     * most of these values are immediately sign-extended to 32 bit by the backend
-                     * (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
-                     * expect).
-                     */
-                    ValueNode value = ((ZeroExtendNode) node).getValue();
-                    if (!mightBeOptimized(value)) {
-                        // if the value is not optimized further by the address lowering, then we
-                        // can safely rely on the backend doing the implicitly zero-extension.
-                        return value;
-                    }
-                }
+            if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
+                assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
+
+                /*
+                 * we can't swallow zero-extends because of multiple reasons:
+                 *
+                 * a) we might encounter something like the following: ZeroExtend(Add(negativeValue,
+                 * positiveValue)). if we swallow the zero-extend in this case and subsequently
+                 * optimize the add, we might end up with a negative value that has less than 64
+                 * bits in base or index. such a value would require sign extension instead of
+                 * zero-extension but the backend can only do (implicit) zero-extension by using a
+                 * larger register (e.g., rax instead of eax).
+                 *
+                 * b) our backend does not guarantee that the upper half of a 64-bit register equals
+                 * 0 if a 32-bit value is stored in there.
+                 *
+                 * c) we also can't swallow zero-extends with less than 32 bits as most of these
+                 * values are immediately sign-extended to 32 bit by the backend (therefore, the
+                 * subsequent implicit zero-extension to 64 bit won't do what we expect).
+                 */
 
                 if (node instanceof AddNode) {
                     AddNode add = (AddNode) node;
@@ -221,13 +222,6 @@
         return node;
     }
 
-    /**
-     * This method returns true for all nodes that might be optimized by the address lowering.
-     */
-    protected boolean mightBeOptimized(ValueNode value) {
-        return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
-    }
-
     private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
         if (c.getJavaKind().isNumericInteger()) {
             long delta = c.asLong() << shift;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -113,7 +114,7 @@
             }
         }
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new AMD64AddressValue(kind, baseValue, indexValue, scale, displacement));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Fri Dec 01 11:17:45 2017 -0800
@@ -99,8 +99,9 @@
 import org.graalvm.compiler.lir.amd64.AMD64Binary;
 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 import org.graalvm.compiler.lir.amd64.AMD64ClearRegisterOp;
+import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
 import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp;
-import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
+import org.graalvm.compiler.lir.amd64.AMD64Move;
 import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
 import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
 import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
@@ -287,14 +288,33 @@
         return ((AMD64Kind) kind).isInteger();
     }
 
+    private Variable emitBaseOffsetLea(LIRKind resultKind, Value base, int offset, OperandSize size) {
+        Variable result = getLIRGen().newVariable(resultKind);
+        AMD64AddressValue address = new AMD64AddressValue(resultKind, getLIRGen().asAllocatable(base), offset);
+        getLIRGen().append(new AMD64Move.LeaOp(result, address, size));
+        return result;
+    }
+
     @Override
     public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
         TargetDescription target = getLIRGen().target();
         boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX);
         switch ((AMD64Kind) a.getPlatformKind()) {
             case DWORD:
+                if (isJavaConstant(b) && !setFlags) {
+                    long displacement = asJavaConstant(b).asLong();
+                    if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
+                        return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.DWORD);
+                    }
+                }
                 return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags);
             case QWORD:
+                if (isJavaConstant(b) && !setFlags) {
+                    long displacement = asJavaConstant(b).asLong();
+                    if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
+                        return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.QWORD);
+                    }
+                }
                 return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags);
             case SINGLE:
                 if (isAvx) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactory.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
 import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
 
+import org.graalvm.compiler.asm.amd64.AMD64Assembler;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
@@ -85,7 +86,7 @@
     @Override
     public AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof AMD64AddressValue) {
-            return new LeaOp(dst, (AMD64AddressValue) src);
+            return new LeaOp(dst, (AMD64AddressValue) src, AMD64Assembler.OperandSize.QWORD);
         } else if (isConstantValue(src)) {
             return createLoad(dst, asConstant(src));
         } else if (isRegister(src) || isStackSlotValue(dst)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Fri Dec 01 11:17:45 2017 -0800
@@ -60,6 +60,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
@@ -478,7 +479,7 @@
     @MatchRule("(Write object Narrow=narrow)")
     public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
         return builder -> {
-            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
+            LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp(NodeView.DEFAULT));
             getArithmeticLIRGenerator().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
             return null;
         };
@@ -504,10 +505,10 @@
             @Override
             public Value evaluate(NodeLIRBuilder builder) {
                 AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
-                LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp()),
+                LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp(NodeView.DEFAULT)),
                                 address.getBase(), address.getIndex());
                 AMD64AddressValue newAddress = address.withKind(addressKind);
-                LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp());
+                LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
                 return getArithmeticLIRGenerator().emitZeroExtendMemory((AMD64Kind) readKind.getPlatformKind(),
                                 root.getResultBits(), newAddress, getState(access));
             }
@@ -517,7 +518,7 @@
     @MatchRule("(SignExtend (Narrow=narrow Read=access))")
     @MatchRule("(SignExtend (Narrow=narrow FloatingRead=access))")
     public ComplexMatchResult signExtendNarrowRead(SignExtendNode root, NarrowNode narrow, LIRLowerableAccess access) {
-        LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp());
+        LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp(NodeView.DEFAULT));
         return emitSignExtendMemory(access, narrow.getResultBits(), root.getResultBits(), kind);
     }
 
@@ -554,7 +555,7 @@
     @MatchRule("(Reinterpret FloatingRead=access)")
     public ComplexMatchResult reinterpret(ReinterpretNode root, LIRLowerableAccess access) {
         return builder -> {
-            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
+            LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
             return emitReinterpretMemory(kind, access);
         };
 
@@ -563,7 +564,7 @@
     @MatchRule("(Write object Reinterpret=reinterpret)")
     public ComplexMatchResult writeReinterpret(WriteNode root, ReinterpretNode reinterpret) {
         return builder -> {
-            LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp());
+            LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp(NodeView.DEFAULT));
             AllocatableValue value = getLIRGeneratorTool().asAllocatable(operand(reinterpret.getValue()));
 
             AMD64AddressValue address = (AMD64AddressValue) operand(root.getAddress());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java	Fri Dec 01 11:17:45 2017 -0800
@@ -251,22 +251,34 @@
     }
 
     public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method) {
-        Signature sig = method.getSignature();
-        Stamp[] result = new Stamp[sig.getParameterCount(!method.isStatic())];
+        return createParameterStamps(assumptions, method, false);
+    }
+
+    public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method, boolean trustInterfaceTypes) {
+        Signature signature = method.getSignature();
+        Stamp[] result = new Stamp[signature.getParameterCount(method.hasReceiver())];
+
         int index = 0;
-
-        if (!method.isStatic()) {
-            result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, method.getDeclaringClass()));
+        ResolvedJavaType accessingClass = method.getDeclaringClass();
+        if (method.hasReceiver()) {
+            if (trustInterfaceTypes) {
+                result[index++] = StampFactory.objectNonNull(TypeReference.createTrusted(assumptions, accessingClass));
+            } else {
+                result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, accessingClass));
+            }
         }
 
-        int max = sig.getParameterCount(false);
-        ResolvedJavaType accessingClass = method.getDeclaringClass();
-        for (int i = 0; i < max; i++) {
-            JavaType type = sig.getParameterType(i, accessingClass);
+        for (int i = 0; i < signature.getParameterCount(false); i++) {
+            JavaType type = signature.getParameterType(i, accessingClass);
             JavaKind kind = type.getJavaKind();
+
             Stamp stamp;
             if (kind == JavaKind.Object && type instanceof ResolvedJavaType) {
-                stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
+                if (trustInterfaceTypes) {
+                    stamp = StampFactory.object(TypeReference.createTrusted(assumptions, (ResolvedJavaType) type));
+                } else {
+                    stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
+                }
             } else {
                 stamp = StampFactory.forKind(kind);
             }
@@ -284,16 +296,28 @@
         if (returnType.getJavaKind() == JavaKind.Object && returnType instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedJavaType = (ResolvedJavaType) returnType;
             TypeReference reference = TypeReference.create(assumptions, resolvedJavaType);
-            if (resolvedJavaType.isInterface()) {
-                ResolvedJavaType implementor = resolvedJavaType.getSingleImplementor();
-                if (implementor != null && !resolvedJavaType.equals(implementor)) {
-                    TypeReference uncheckedType = TypeReference.createTrusted(assumptions, implementor);
-                    return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
+            ResolvedJavaType elementalType = resolvedJavaType.getElementalType();
+            if (elementalType.isInterface()) {
+                assert reference == null || !reference.getType().equals(resolvedJavaType);
+                TypeReference uncheckedType;
+                ResolvedJavaType elementalImplementor = elementalType.getSingleImplementor();
+                if (elementalImplementor != null && !elementalType.equals(elementalImplementor)) {
+                    ResolvedJavaType implementor = elementalImplementor;
+                    ResolvedJavaType t = resolvedJavaType;
+                    while (t.isArray()) {
+                        implementor = implementor.getArrayClass();
+                        t = t.getComponentType();
+                    }
+                    uncheckedType = TypeReference.createTrusted(assumptions, implementor);
+                } else {
+                    uncheckedType = TypeReference.createTrusted(assumptions, resolvedJavaType);
                 }
+                return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
             }
             return StampPair.createSingle(StampFactory.object(reference, nonNull));
         } else {
             return StampPair.createSingle(StampFactory.forKind(returnType.getJavaKind()));
         }
     }
+
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCAddressLowering.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCAddressLowering.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,11 +34,6 @@
 public class SPARCAddressLowering extends AddressLowering {
 
     @Override
-    public AddressNode lower(ValueNode address) {
-        return lower(address, 0);
-    }
-
-    @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
         JavaConstant immBase = asImmediate(base);
         if (immBase != null && SPARCAssembler.isSimm13(immBase)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCImmediateAddressNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCImmediateAddressNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.sparc.SPARCImmediateAddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -59,7 +60,7 @@
 
         AllocatableValue baseValue = tool.asAllocatable(gen.operand(base));
 
-        LIRKind kind = tool.getLIRKind(stamp());
+        LIRKind kind = tool.getLIRKind(stamp(NodeView.DEFAULT));
         AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
         if (baseReference != null) {
             kind = kind.makeDerivedReference(baseReference);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIndexedAddressNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIndexedAddressNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.sparc.SPARCIndexedAddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -61,7 +62,7 @@
         AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
         AllocatableValue indexReference = LIRKind.derivedBaseFromValue(indexValue);
 
-        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
+        LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
         gen.setResult(this, new SPARCIndexedAddressValue(kind, baseValue, indexValue));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIntegerCompareCanonicalizationPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCIntegerCompareCanonicalizationPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -59,7 +60,7 @@
     }
 
     private static void min32(CompareNode enode, ValueNode v) {
-        Stamp s = v.stamp();
+        Stamp s = v.stamp(NodeView.DEFAULT);
         if (s instanceof IntegerStamp) {
             int bits = ((IntegerStamp) s).getBits();
             if (bits != 32 && bits != 64) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -25,6 +25,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
 
+import org.graalvm.compiler.nodes.NodeView;
 import org.junit.Test;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
@@ -223,7 +224,7 @@
         @Input private ValueNode iv;
 
         protected IVPropertyNode(IVProperty property, ValueNode iv) {
-            super(TYPE, iv.stamp().unrestricted());
+            super(TYPE, iv.stamp(NodeView.DEFAULT).unrestricted());
             this.property = property;
             this.iv = iv;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -166,7 +166,8 @@
         ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer();
         StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet"));
         new CanonicalizerPhase(c2).apply(g2, htc);
-        Assert.assertTrue(c1.savedCycles > c2.savedCycles);
+        Assert.assertEquals(0, c1.savedCycles);
+        Assert.assertEquals(0, c2.savedCycles);
     }
 
     private static void prepareGraphForLoopFrequencies(StructuredGraph g, HighTierContext htc) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UncheckedInterfaceProviderTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.test;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+
+import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodeinfo.Verbosity;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.debug.BlackholeNode;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
+import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
+import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class UncheckedInterfaceProviderTest extends GraalCompilerTest {
+    private Runnable interfaceField;
+    private Runnable[] interfaceArrayField;
+
+    public void snippet(Runnable interfaceParameter, Runnable[] interfaceArrayParameter) {
+        GraalDirectives.blackhole(interfaceParameter);
+        GraalDirectives.blackhole(interfaceArrayParameter);
+        GraalDirectives.blackhole(interfaceField);
+        GraalDirectives.blackhole(interfaceArrayField);
+        GraalDirectives.blackhole(interfaceReturn());
+        GraalDirectives.blackhole(interfaceArrayReturn());
+        GraalDirectives.blackhole(interfaceReturnException());
+        GraalDirectives.blackhole(interfaceArrayReturnException());
+    }
+
+    public static Runnable interfaceReturn() {
+        return new A();
+    }
+
+    public static Runnable[] interfaceArrayReturn() {
+        return new Runnable[]{new A(), new B(), new C(), new D()};
+    }
+
+    public static Runnable interfaceReturnException() {
+        return new A();
+    }
+
+    public static Runnable[] interfaceArrayReturnException() {
+        return new Runnable[]{new A(), new B(), new C(), new D()};
+    }
+
+    @Override
+    protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
+        if (method.getName().startsWith("interfaceReturn") || method.getName().startsWith("interfaceArrayReturn")) {
+            if (method.getName().equals("Exception")) {
+                return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
+            }
+            return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
+        }
+        return super.bytecodeParserShouldInlineInvoke(b, method, args);
+    }
+
+    @BeforeClass
+    public static void setup() {
+        interfaceArrayReturn();
+    }
+
+    @Test
+    public void test() {
+        StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
+        for (BlackholeNode b : graph.getNodes().filter(BlackholeNode.class)) {
+            Assert.assertThat(b.getValue(), is(instanceOf(UncheckedInterfaceProvider.class)));
+            Stamp uncheckedStamp = ((UncheckedInterfaceProvider) b.getValue()).uncheckedStamp();
+            String context = b.getValue().toString(Verbosity.Debugger);
+            Assert.assertNotNull(context, uncheckedStamp);
+            ResolvedJavaType uncheckedType = StampTool.typeOrNull(uncheckedStamp);
+            ResolvedJavaType type = StampTool.typeOrNull(b.getValue());
+            Assert.assertEquals(context, arrayDepth(type), arrayDepth(uncheckedType));
+            Assert.assertTrue(context + ": " + type, type == null || type.getElementalType().isJavaLangObject());
+            Assert.assertNotNull(context, uncheckedType);
+            Assert.assertTrue(context, uncheckedType.getElementalType().isInterface());
+        }
+    }
+
+    private static int arrayDepth(ResolvedJavaType type) {
+        int depth = 0;
+        ResolvedJavaType t = type;
+        while (t != null && t.isArray()) {
+            depth += 1;
+            t = t.getComponentType();
+        }
+        return depth;
+    }
+
+    public static class A implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class B implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class C implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+
+    public static class D implements Runnable {
+        @Override
+        public void run() {
+            // nop
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -22,14 +22,7 @@
  */
 package org.graalvm.compiler.core.test.deopt;
 
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.InvalidInstalledCodeException;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-import org.junit.Assert;
-import org.junit.Test;
-
+import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -37,16 +30,19 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Test;
 
-/**
- * In the following tests, the usages of local variable "a" are replaced with the integer constant
- * 0. Then canonicalization is applied and it is verified that the resulting graph is equal to the
- * graph of the method that just has a "return 1" statement in it.
- */
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class CompiledMethodTest extends GraalCompilerTest {
 
     public static Object testMethod(Object arg1, Object arg2, Object arg3) {
-        return arg1 + " " + arg2 + " " + arg3;
+        String res = arg1 + " " + arg2 + " " + arg3;
+        return GraalDirectives.inCompiledCode() ? res : "interpreter";
     }
 
     Object f1;
@@ -55,6 +51,12 @@
         return f1 + " " + arg1 + " " + arg2 + " " + arg3;
     }
 
+    /**
+     * Usages of the constant {@code " "} are replaced with the constant {@code "-"} and it is
+     * verified that executing the compiled code produces a result that the preserves the node
+     * replacement unless deoptimization occurs (e.g., due to -Xcomp causing profiles to be
+     * missing).
+     */
     @Test
     public void test1() {
         final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
@@ -71,7 +73,10 @@
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             Object result = compiledMethod.executeVarargs("1", "2", "3");
-            Assert.assertEquals("1-2-3", result);
+            if (!"1-2-3".equals(result)) {
+                // Deoptimization probably occurred
+                Assert.assertEquals("interpreter", result);
+            }
         } catch (InvalidInstalledCodeException t) {
             Assert.fail("method invalidated");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeUnsafeStoreTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.test.ea;
+
+import java.lang.reflect.Field;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.junit.Test;
+
+import sun.misc.Unsafe;
+
+/**
+ * Exercise a mix of unsafe and normal reads ands writes in situations where EA might attempt to
+ * fold the operations.
+ */
+public class PartialEscapeUnsafeStoreTest extends GraalCompilerTest {
+
+    private static final Unsafe unsafe = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafe.setAccessible(true);
+            return (Unsafe) theUnsafe.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe", e);
+        }
+    }
+
+    private static final long byteArrayBaseOffset = unsafe.arrayBaseOffset(byte[].class);
+    private static byte byteValue = 0x61;
+
+    public static byte[] testByteArrayWithCharStoreSnippet(char v) {
+        byte[] b = new byte[8];
+        unsafe.putChar(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithCharStore() {
+        test("testByteArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static byte[] testByteArrayWithShortStoreSnippet(short v) {
+        byte[] b = new byte[8];
+        unsafe.putShort(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithShortStore() {
+        test("testByteArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static byte[] testByteArrayWithIntStoreSnippet(int v) {
+        byte[] b = new byte[8];
+        unsafe.putInt(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithIntStore() {
+        test("testByteArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static byte[] testByteArrayWithLongStoreSnippet(long v) {
+        byte[] b = new byte[8];
+        unsafe.putLong(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithLongStore() {
+        test("testByteArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static byte[] testByteArrayWithFloatStoreSnippet(float v) {
+        byte[] b = new byte[8];
+        unsafe.putFloat(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithFloatStore() {
+        test("testByteArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static byte[] testByteArrayWithDoubleStoreSnippet(double v) {
+        byte[] b = new byte[8];
+        unsafe.putDouble(b, byteArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testByteArrayWithDoubleStore() {
+        test("testByteArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long charArrayBaseOffset = unsafe.arrayBaseOffset(char[].class);
+    private static char charValue = 0x4142;
+
+    public static char[] testCharArrayWithByteStoreSnippet(byte v) {
+        char[] b = new char[4];
+        unsafe.putByte(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithByteStore() {
+        test("testCharArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static char[] testCharArrayWithShortStoreSnippet(short v) {
+        char[] b = new char[4];
+        unsafe.putShort(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithShortStore() {
+        test("testCharArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static char[] testCharArrayWithIntStoreSnippet(int v) {
+        char[] b = new char[4];
+        unsafe.putInt(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithIntStore() {
+        test("testCharArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static char[] testCharArrayWithLongStoreSnippet(long v) {
+        char[] b = new char[4];
+        unsafe.putLong(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithLongStore() {
+        test("testCharArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static char[] testCharArrayWithFloatStoreSnippet(float v) {
+        char[] b = new char[4];
+        unsafe.putFloat(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithFloatStore() {
+        test("testCharArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static char[] testCharArrayWithDoubleStoreSnippet(double v) {
+        char[] b = new char[4];
+        unsafe.putDouble(b, charArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testCharArrayWithDoubleStore() {
+        test("testCharArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long shortArrayBaseOffset = unsafe.arrayBaseOffset(short[].class);
+    private static short shortValue = 0x1112;
+
+    public static short[] testShortArrayWithByteStoreSnippet(byte v) {
+        short[] b = new short[4];
+        unsafe.putByte(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithByteStore() {
+        test("testShortArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static short[] testShortArrayWithCharStoreSnippet(char v) {
+        short[] b = new short[4];
+        unsafe.putChar(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithCharStore() {
+        test("testShortArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static short[] testShortArrayWithIntStoreSnippet(int v) {
+        short[] b = new short[4];
+        unsafe.putInt(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithIntStore() {
+        test("testShortArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static short[] testShortArrayWithLongStoreSnippet(long v) {
+        short[] b = new short[4];
+        unsafe.putLong(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithLongStore() {
+        test("testShortArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static short[] testShortArrayWithFloatStoreSnippet(float v) {
+        short[] b = new short[4];
+        unsafe.putFloat(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithFloatStore() {
+        test("testShortArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static short[] testShortArrayWithDoubleStoreSnippet(double v) {
+        short[] b = new short[4];
+        unsafe.putDouble(b, shortArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testShortArrayWithDoubleStore() {
+        test("testShortArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long intArrayBaseOffset = unsafe.arrayBaseOffset(int[].class);
+    private static int intValue = 0x01020304;
+
+    public static int[] testIntArrayWithByteStoreSnippet(byte v) {
+        int[] b = new int[4];
+        unsafe.putByte(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithByteStore() {
+        test("testIntArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static int[] testIntArrayWithCharStoreSnippet(char v) {
+        int[] b = new int[4];
+        unsafe.putChar(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithCharStore() {
+        test("testIntArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static int[] testIntArrayWithShortStoreSnippet(short v) {
+        int[] b = new int[4];
+        unsafe.putShort(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithShortStore() {
+        test("testIntArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static int[] testIntArrayWithLongStoreSnippet(long v) {
+        int[] b = new int[4];
+        unsafe.putLong(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithLongStore() {
+        test("testIntArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static int[] testIntArrayWithFloatStoreSnippet(float v) {
+        int[] b = new int[4];
+        unsafe.putFloat(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithFloatStore() {
+        test("testIntArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static int[] testIntArrayWithDoubleStoreSnippet(double v) {
+        int[] b = new int[4];
+        unsafe.putDouble(b, intArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testIntArrayWithDoubleStore() {
+        test("testIntArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long longArrayBaseOffset = unsafe.arrayBaseOffset(long[].class);
+    private static long longValue = 0x31323334353637L;
+
+    public static long[] testLongArrayWithByteStoreSnippet(byte v) {
+        long[] b = new long[4];
+        unsafe.putByte(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithByteStore() {
+        test("testLongArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static long[] testLongArrayWithCharStoreSnippet(char v) {
+        long[] b = new long[4];
+        unsafe.putChar(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithCharStore() {
+        test("testLongArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static long[] testLongArrayWithShortStoreSnippet(short v) {
+        long[] b = new long[4];
+        unsafe.putShort(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithShortStore() {
+        test("testLongArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static long[] testLongArrayWithIntStoreSnippet(int v) {
+        long[] b = new long[4];
+        unsafe.putInt(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithIntStore() {
+        test("testLongArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static long[] testLongArrayWithFloatStoreSnippet(float v) {
+        long[] b = new long[4];
+        unsafe.putFloat(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithFloatStore() {
+        test("testLongArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static long[] testLongArrayWithDoubleStoreSnippet(double v) {
+        long[] b = new long[4];
+        unsafe.putDouble(b, longArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testLongArrayWithDoubleStore() {
+        test("testLongArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long floatArrayBaseOffset = unsafe.arrayBaseOffset(float[].class);
+    private static float floatValue = Float.NaN;
+
+    public static float[] testFloatArrayWithByteStoreSnippet(byte v) {
+        float[] b = new float[4];
+        unsafe.putByte(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithByteStore() {
+        test("testFloatArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static float[] testFloatArrayWithCharStoreSnippet(char v) {
+        float[] b = new float[4];
+        unsafe.putChar(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithCharStore() {
+        test("testFloatArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static float[] testFloatArrayWithShortStoreSnippet(short v) {
+        float[] b = new float[4];
+        unsafe.putShort(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithShortStore() {
+        test("testFloatArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static float[] testFloatArrayWithIntStoreSnippet(int v) {
+        float[] b = new float[4];
+        unsafe.putInt(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithIntStore() {
+        test("testFloatArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static float[] testFloatArrayWithLongStoreSnippet(long v) {
+        float[] b = new float[4];
+        unsafe.putLong(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithLongStore() {
+        test("testFloatArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static float[] testFloatArrayWithDoubleStoreSnippet(double v) {
+        float[] b = new float[4];
+        unsafe.putDouble(b, floatArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testFloatArrayWithDoubleStore() {
+        test("testFloatArrayWithDoubleStoreSnippet", doubleValue);
+    }
+
+    private static final long doubleArrayBaseOffset = unsafe.arrayBaseOffset(double[].class);
+    private static double doubleValue = Double.NaN;
+    private static final int byteSize = 1;
+    private static final int charSize = 2;
+    private static final int shortSize = 2;
+    private static final int intSize = 4;
+    private static final int floatSize = 4;
+    private static final int longSize = 8;
+    private static final int doubleSize = 8;
+
+    public static double[] testDoubleArrayWithByteStoreSnippet(byte v) {
+        double[] b = new double[4];
+        unsafe.putByte(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithByteStore() {
+        test("testDoubleArrayWithByteStoreSnippet", byteValue);
+    }
+
+    public static double[] testDoubleArrayWithCharStoreSnippet(char v) {
+        double[] b = new double[4];
+        unsafe.putChar(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithCharStore() {
+        test("testDoubleArrayWithCharStoreSnippet", charValue);
+    }
+
+    public static double[] testDoubleArrayWithShortStoreSnippet(short v) {
+        double[] b = new double[4];
+        unsafe.putShort(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithShortStore() {
+        test("testDoubleArrayWithShortStoreSnippet", shortValue);
+    }
+
+    public static double[] testDoubleArrayWithIntStoreSnippet(int v) {
+        double[] b = new double[4];
+        unsafe.putInt(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithIntStore() {
+        test("testDoubleArrayWithIntStoreSnippet", intValue);
+    }
+
+    public static double[] testDoubleArrayWithLongStoreSnippet(long v) {
+        double[] b = new double[4];
+        unsafe.putLong(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithLongStore() {
+        test("testDoubleArrayWithLongStoreSnippet", longValue);
+    }
+
+    public static double[] testDoubleArrayWithFloatStoreSnippet(float v) {
+        double[] b = new double[4];
+        unsafe.putFloat(b, doubleArrayBaseOffset, v);
+        return b;
+    }
+
+    @Test
+    public void testDoubleArrayWithFloatStore() {
+        test("testDoubleArrayWithFloatStoreSnippet", floatValue);
+    }
+
+    public static byte testByteArrayWithCharStoreAndReadSnippet(char v) {
+        byte[] b = new byte[4];
+        unsafe.putChar(b, byteArrayBaseOffset, v);
+        return b[(byteSize / charSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithCharStoreAndRead() {
+        test("testByteArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static byte testByteArrayWithShortStoreAndReadSnippet(short v) {
+        byte[] b = new byte[4];
+        unsafe.putShort(b, byteArrayBaseOffset, v);
+        return b[(byteSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithShortStoreAndRead() {
+        test("testByteArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static byte testByteArrayWithIntStoreAndReadSnippet(int v) {
+        byte[] b = new byte[4];
+        unsafe.putInt(b, byteArrayBaseOffset, v);
+        return b[(byteSize / intSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithIntStoreAndRead() {
+        test("testByteArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static byte testByteArrayWithLongStoreAndReadSnippet(long v) {
+        byte[] b = new byte[4];
+        unsafe.putLong(b, byteArrayBaseOffset, v);
+        return b[(byteSize / longSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithLongStoreAndRead() {
+        test("testByteArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static byte testByteArrayWithFloatStoreAndReadSnippet(float v) {
+        byte[] b = new byte[4];
+        unsafe.putFloat(b, byteArrayBaseOffset, v);
+        return b[(byteSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithFloatStoreAndRead() {
+        test("testByteArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static byte testByteArrayWithDoubleStoreAndReadSnippet(double v) {
+        byte[] b = new byte[4];
+        unsafe.putDouble(b, byteArrayBaseOffset, v);
+        return b[(byteSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testByteArrayWithDoubleStoreAndRead() {
+        test("testByteArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static char testCharArrayWithByteStoreAndReadSnippet(byte v) {
+        char[] b = new char[4];
+        unsafe.putByte(b, charArrayBaseOffset, v);
+        return b[(charSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithByteStoreAndRead() {
+        test("testCharArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static char testCharArrayWithShortStoreAndReadSnippet(short v) {
+        char[] b = new char[4];
+        unsafe.putShort(b, charArrayBaseOffset, v);
+        return b[(charSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithShortStoreAndRead() {
+        test("testCharArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static char testCharArrayWithIntStoreAndReadSnippet(int v) {
+        char[] b = new char[4];
+        unsafe.putInt(b, charArrayBaseOffset, v);
+        return b[(charSize / intSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithIntStoreAndRead() {
+        test("testCharArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static char testCharArrayWithLongStoreAndReadSnippet(long v) {
+        char[] b = new char[4];
+        unsafe.putLong(b, charArrayBaseOffset, v);
+        return b[(charSize / longSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithLongStoreAndRead() {
+        test("testCharArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static char testCharArrayWithFloatStoreAndReadSnippet(float v) {
+        char[] b = new char[4];
+        unsafe.putFloat(b, charArrayBaseOffset, v);
+        return b[(charSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithFloatStoreAndRead() {
+        test("testCharArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static char testCharArrayWithDoubleStoreAndReadSnippet(double v) {
+        char[] b = new char[4];
+        unsafe.putDouble(b, charArrayBaseOffset, v);
+        return b[(charSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testCharArrayWithDoubleStoreAndRead() {
+        test("testCharArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static short testShortArrayWithByteStoreAndReadSnippet(byte v) {
+        short[] b = new short[4];
+        unsafe.putByte(b, shortArrayBaseOffset, v);
+        return b[(shortSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithByteStoreAndRead() {
+        test("testShortArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static short testShortArrayWithCharStoreAndReadSnippet(char v) {
+        short[] b = new short[4];
+        unsafe.putChar(b, shortArrayBaseOffset, v);
+        return b[(shortSize / charSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithCharStoreAndRead() {
+        test("testShortArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static short testShortArrayWithIntStoreAndReadSnippet(int v) {
+        short[] b = new short[4];
+        unsafe.putInt(b, shortArrayBaseOffset, v);
+        return b[(shortSize / intSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithIntStoreAndRead() {
+        test("testShortArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static short testShortArrayWithLongStoreAndReadSnippet(long v) {
+        short[] b = new short[4];
+        unsafe.putLong(b, shortArrayBaseOffset, v);
+        return b[(shortSize / longSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithLongStoreAndRead() {
+        test("testShortArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static short testShortArrayWithFloatStoreAndReadSnippet(float v) {
+        short[] b = new short[4];
+        unsafe.putFloat(b, shortArrayBaseOffset, v);
+        return b[(shortSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithFloatStoreAndRead() {
+        test("testShortArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static short testShortArrayWithDoubleStoreAndReadSnippet(double v) {
+        short[] b = new short[4];
+        unsafe.putDouble(b, shortArrayBaseOffset, v);
+        return b[(shortSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testShortArrayWithDoubleStoreAndRead() {
+        test("testShortArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static int testIntArrayWithByteStoreAndReadSnippet(byte v) {
+        int[] b = new int[4];
+        unsafe.putByte(b, intArrayBaseOffset, v);
+        return b[(intSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithByteStoreAndRead() {
+        test("testIntArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static int testIntArrayWithCharStoreAndReadSnippet(char v) {
+        int[] b = new int[4];
+        unsafe.putChar(b, intArrayBaseOffset, v);
+        return b[(intSize / charSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithCharStoreAndRead() {
+        test("testIntArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static int testIntArrayWithShortStoreAndReadSnippet(short v) {
+        int[] b = new int[4];
+        unsafe.putShort(b, intArrayBaseOffset, v);
+        return b[(intSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithShortStoreAndRead() {
+        test("testIntArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static int testIntArrayWithLongStoreAndReadSnippet(long v) {
+        int[] b = new int[4];
+        unsafe.putLong(b, intArrayBaseOffset, v);
+        return b[(intSize / longSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithLongStoreAndRead() {
+        test("testIntArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static int testIntArrayWithFloatStoreAndReadSnippet(float v) {
+        int[] b = new int[4];
+        unsafe.putFloat(b, intArrayBaseOffset, v);
+        return b[(intSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithFloatStoreAndRead() {
+        test("testIntArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static int testIntArrayWithDoubleStoreAndReadSnippet(double v) {
+        int[] b = new int[4];
+        unsafe.putDouble(b, intArrayBaseOffset, v);
+        return b[(intSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testIntArrayWithDoubleStoreAndRead() {
+        test("testIntArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static long testLongArrayWithByteStoreAndReadSnippet(byte v) {
+        long[] b = new long[4];
+        unsafe.putByte(b, longArrayBaseOffset, v);
+        return b[(longSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithByteStoreAndRead() {
+        test("testLongArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static long testLongArrayWithCharStoreAndReadSnippet(char v) {
+        long[] b = new long[4];
+        unsafe.putChar(b, longArrayBaseOffset, v);
+        return b[(longSize / charSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithCharStoreAndRead() {
+        test("testLongArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static long testLongArrayWithShortStoreAndReadSnippet(short v) {
+        long[] b = new long[4];
+        unsafe.putShort(b, longArrayBaseOffset, v);
+        return b[(longSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithShortStoreAndRead() {
+        test("testLongArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static long testLongArrayWithIntStoreAndReadSnippet(int v) {
+        long[] b = new long[4];
+        unsafe.putInt(b, longArrayBaseOffset, v);
+        return b[(longSize / intSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithIntStoreAndRead() {
+        test("testLongArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static long testLongArrayWithFloatStoreAndReadSnippet(float v) {
+        long[] b = new long[4];
+        unsafe.putFloat(b, longArrayBaseOffset, v);
+        return b[(longSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithFloatStoreAndRead() {
+        test("testLongArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+
+    public static long testLongArrayWithDoubleStoreAndReadSnippet(double v) {
+        long[] b = new long[4];
+        unsafe.putDouble(b, longArrayBaseOffset, v);
+        return b[(longSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testLongArrayWithDoubleStoreAndRead() {
+        test("testLongArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static float testFloatArrayWithByteStoreAndReadSnippet(byte v) {
+        float[] b = new float[4];
+        unsafe.putByte(b, floatArrayBaseOffset, v);
+        return b[(floatSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithByteStoreAndRead() {
+        test("testFloatArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static float testFloatArrayWithCharStoreAndReadSnippet(char v) {
+        float[] b = new float[4];
+        unsafe.putChar(b, floatArrayBaseOffset, v);
+        return b[(floatSize / charSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithCharStoreAndRead() {
+        test("testFloatArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static float testFloatArrayWithShortStoreAndReadSnippet(short v) {
+        float[] b = new float[4];
+        unsafe.putShort(b, floatArrayBaseOffset, v);
+        return b[(floatSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithShortStoreAndRead() {
+        test("testFloatArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static float testFloatArrayWithIntStoreAndReadSnippet(int v) {
+        float[] b = new float[4];
+        unsafe.putInt(b, floatArrayBaseOffset, v);
+        return b[(floatSize / intSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithIntStoreAndRead() {
+        test("testFloatArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static float testFloatArrayWithLongStoreAndReadSnippet(long v) {
+        float[] b = new float[4];
+        unsafe.putLong(b, floatArrayBaseOffset, v);
+        return b[(floatSize / longSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithLongStoreAndRead() {
+        test("testFloatArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static float testFloatArrayWithDoubleStoreAndReadSnippet(double v) {
+        float[] b = new float[4];
+        unsafe.putDouble(b, floatArrayBaseOffset, v);
+        return b[(floatSize / doubleSize) + 1];
+    }
+
+    @Test
+    public void testFloatArrayWithDoubleStoreAndRead() {
+        test("testFloatArrayWithDoubleStoreAndReadSnippet", doubleValue);
+    }
+
+    public static double testDoubleArrayWithByteStoreAndReadSnippet(byte v) {
+        double[] b = new double[4];
+        unsafe.putByte(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / byteSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithByteStoreAndRead() {
+        test("testDoubleArrayWithByteStoreAndReadSnippet", byteValue);
+    }
+
+    public static double testDoubleArrayWithCharStoreAndReadSnippet(char v) {
+        double[] b = new double[4];
+        unsafe.putChar(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / charSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithCharStoreAndRead() {
+        test("testDoubleArrayWithCharStoreAndReadSnippet", charValue);
+    }
+
+    public static double testDoubleArrayWithShortStoreAndReadSnippet(short v) {
+        double[] b = new double[4];
+        unsafe.putShort(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / shortSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithShortStoreAndRead() {
+        test("testDoubleArrayWithShortStoreAndReadSnippet", shortValue);
+    }
+
+    public static double testDoubleArrayWithIntStoreAndReadSnippet(int v) {
+        double[] b = new double[4];
+        unsafe.putInt(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / intSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithIntStoreAndRead() {
+        test("testDoubleArrayWithIntStoreAndReadSnippet", intValue);
+    }
+
+    public static double testDoubleArrayWithLongStoreAndReadSnippet(long v) {
+        double[] b = new double[4];
+        unsafe.putLong(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / longSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithLongStoreAndRead() {
+        test("testDoubleArrayWithLongStoreAndReadSnippet", longValue);
+    }
+
+    public static double testDoubleArrayWithFloatStoreAndReadSnippet(float v) {
+        double[] b = new double[4];
+        unsafe.putFloat(b, doubleArrayBaseOffset, v);
+        return b[(doubleSize / floatSize) + 1];
+    }
+
+    @Test
+    public void testDoubleArrayWithFloatStoreAndRead() {
+        test("testDoubleArrayWithFloatStoreAndReadSnippet", floatValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2012, 2016, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.test.inlining;
+
+import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine;
+import static org.graalvm.compiler.test.SubprocessUtil.java;
+import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugDumpScope;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.InvokeNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.StructuredGraph.Builder;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.nodes.java.TypeSwitchNode;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
+import org.graalvm.compiler.phases.common.inlining.InliningPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+public class PolymorphicInliningTest extends GraalCompilerTest {
+
+    @Test
+    public void testInSubprocess() throws InterruptedException, IOException {
+        String recursionPropName = getClass().getName() + ".recursion";
+        if (Boolean.getBoolean(recursionPropName)) {
+            testPolymorphicInlining();
+            testPolymorphicNotInlining();
+            testMegamorphicInlining();
+            testMegamorphicNotInlining();
+        } else {
+            List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
+            NotInlinableSubClass.class.getCanonicalName();
+            vmArgs.add("-XX:CompileCommand=dontinline,org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest$NotInlinableSubClass.publicOverriddenMethod");
+            vmArgs.add("-D" + recursionPropName + "=true");
+            SubprocessUtil.Subprocess proc = java(vmArgs, "com.oracle.mxtool.junit.MxJUnitWrapper", getClass().getName());
+            if (proc.exitCode != 0) {
+                Assert.fail(String.format("non-zero exit code %d for command:%n%s", proc.exitCode, proc));
+            }
+        }
+    }
+
+    public int polymorphicCallsite(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testPolymorphicInlining() {
+        for (int i = 0; i < 10000; i++) {
+            if (i % 2 == 0) {
+                polymorphicCallsite(Receivers.subClassA);
+            } else {
+                polymorphicCallsite(Receivers.subClassB);
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite", false);
+        // This callsite should be inlined with a TypeCheckedInliningViolated deoptimization.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 0);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
+        assertTrue(getNodeCount(graph, DeoptimizeNode.class) >= 1);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite1(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testPolymorphicNotInlining() {
+        for (int i = 0; i < 10000; i++) {
+            if (i % 2 == 0) {
+                polymorphicCallsite1(Receivers.subClassA);
+            } else {
+                polymorphicCallsite1(Receivers.notInlinableSubClass);
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite1", false);
+        // This callsite should not be inlined due to one of the potential callee method is not
+        // inlinable.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite2(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testMegamorphicInlining() {
+        // Construct a receiver type profile that exceeds the max type width (by default 8 in JVMCI,
+        // specified by -XX:TypeProfileWidth).
+        for (int i = 0; i < 2000; i++) {
+            // Ensure the following receiver type is within the type profile.
+            polymorphicCallsite2(Receivers.subClassA);
+        }
+        for (int i = 0; i < 10000; i++) {
+            switch (i % 20) {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                case 7:
+                    // Probability: 40%
+                    // Ensure the probability is greater than
+                    // GraalOptions.MegamorphicInliningMinMethodProbability (by default 0.33D);
+                    polymorphicCallsite2(Receivers.subClassA);
+                    break;
+                case 8:
+                    polymorphicCallsite2(Receivers.subClassB);
+                    break;
+                case 9:
+                    polymorphicCallsite2(Receivers.subClassC);
+                    break;
+                case 10:
+                    polymorphicCallsite2(Receivers.subClassD);
+                    break;
+                case 11:
+                    polymorphicCallsite2(Receivers.subClassE);
+                    break;
+                case 12:
+                    polymorphicCallsite2(Receivers.subClassF);
+                    break;
+                case 13:
+                    polymorphicCallsite2(Receivers.subClassG);
+                    break;
+                case 14:
+                    polymorphicCallsite2(Receivers.subClassH);
+                    break;
+                default:
+                    // Probability: 25%
+                    polymorphicCallsite2(Receivers.notInlinableSubClass);
+                    break;
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite2", false);
+        // This callsite should be inlined with a fallback invocation.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
+    }
+
+    /**
+     * This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
+     * interference of the receiver type profile from different unit tests.
+     */
+    public int polymorphicCallsite3(SuperClass receiver) {
+        return receiver.publicOverriddenMethod();
+    }
+
+    public void testMegamorphicNotInlining() {
+        for (int i = 0; i < 10000; i++) {
+            switch (i % 10) {
+                case 0:
+                case 1:
+                    polymorphicCallsite3(Receivers.subClassA);
+                    break;
+                case 2:
+                    polymorphicCallsite3(Receivers.subClassB);
+                    break;
+                case 3:
+                    polymorphicCallsite3(Receivers.subClassC);
+                    break;
+                case 4:
+                    polymorphicCallsite3(Receivers.subClassD);
+                    break;
+                case 5:
+                    polymorphicCallsite3(Receivers.subClassE);
+                    break;
+                case 6:
+                    polymorphicCallsite3(Receivers.subClassF);
+                    break;
+                case 7:
+                    polymorphicCallsite3(Receivers.subClassG);
+                    break;
+                case 8:
+                    polymorphicCallsite3(Receivers.subClassH);
+                    break;
+                default:
+                    polymorphicCallsite3(Receivers.notInlinableSubClass);
+                    break;
+            }
+        }
+        StructuredGraph graph = getGraph("polymorphicCallsite3", false);
+        // This callsite should not be inlined due to non of the potential callee method exceeds the
+        // probability specified by GraalOptions.MegamorphicInliningMinMethodProbability.
+        assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
+        assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
+    }
+
+    @SuppressWarnings("try")
+    private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
+        DebugContext debug = getDebugContext();
+        try (DebugContext.Scope s = debug.scope("InliningTest", new DebugDumpScope(snippet, true))) {
+            ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+            Builder builder = builder(method, AllowAssumptions.YES, debug);
+            StructuredGraph graph = eagerInfopointMode ? parse(builder, getDebugGraphBuilderSuite()) : parse(builder, getEagerGraphBuilderSuite());
+            try (DebugContext.Scope s2 = debug.scope("Inlining", graph)) {
+                PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode
+                                ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true))
+                                : getDefaultGraphBuilderSuite();
+                HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
+                debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
+                new CanonicalizerPhase().apply(graph, context);
+                new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
+                debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
+                new CanonicalizerPhase().apply(graph, context);
+                new DeadCodeEliminationPhase().apply(graph);
+                return graph;
+            }
+        } catch (Throwable e) {
+            throw debug.handle(e);
+        }
+    }
+
+    private static int getNodeCount(StructuredGraph graph, Class<? extends Node> nodeClass) {
+        return graph.getNodes().filter(nodeClass).count();
+    }
+
+    private static final class Receivers {
+        static final SubClassA subClassA = new SubClassA();
+        static final SubClassB subClassB = new SubClassB();
+        static final SubClassC subClassC = new SubClassC();
+        static final SubClassD subClassD = new SubClassD();
+        static final SubClassE subClassE = new SubClassE();
+        static final SubClassF subClassF = new SubClassF();
+        static final SubClassG subClassG = new SubClassG();
+        static final SubClassH subClassH = new SubClassH();
+
+        static final NotInlinableSubClass notInlinableSubClass = new NotInlinableSubClass();
+    }
+
+    private abstract static class SuperClass {
+
+        public abstract int publicOverriddenMethod();
+
+    }
+
+    private static class SubClassA extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'A';
+        }
+
+    }
+
+    private static class SubClassB extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'B';
+        }
+
+    }
+
+    private static class SubClassC extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'C';
+        }
+
+    }
+
+    private static class SubClassD extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'D';
+        }
+
+    }
+
+    private static class SubClassE extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'E';
+        }
+
+    }
+
+    private static class SubClassF extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'F';
+        }
+
+    }
+
+    private static class SubClassG extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'G';
+        }
+
+    }
+
+    private static class SubClassH extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'H';
+        }
+
+    }
+
+    private static final class NotInlinableSubClass extends SuperClass {
+
+        @Override
+        public int publicOverriddenMethod() {
+            return 'X';
+        }
+
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -81,6 +81,7 @@
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoweredCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -243,7 +244,7 @@
     }
 
     protected LIRKind getExactPhiKind(PhiNode phi) {
-        LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp()));
+        LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp(NodeView.DEFAULT)));
         /* Collect reference information. */
         for (int i = 0; i < phi.valueCount() && !derivedKind.isUnknownReference(); i++) {
             ValueNode node = phi.valueAt(i);
@@ -255,7 +256,7 @@
                 valueKind = value.getValueKind(LIRKind.class);
             } else {
                 assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
-                LIRKind kind = gen.getLIRKind(node.stamp());
+                LIRKind kind = gen.getLIRKind(node.stamp(NodeView.DEFAULT));
                 valueKind = gen.toRegisterKind(kind);
             }
             /* Merge the reference information of the derived kind and the input. */
@@ -448,7 +449,7 @@
     }
 
     protected void emitNode(ValueNode node) {
-        if (node.getDebug().isLogEnabled() && node.stamp().isEmpty()) {
+        if (node.getDebug().isLogEnabled() && node.stamp(NodeView.DEFAULT).isEmpty()) {
             node.getDebug().log("This node has an empty stamp, we are emitting dead code(?): %s", node);
         }
         setSourcePosition(node.getNodeSourcePosition());
@@ -477,7 +478,8 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp());
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " +
+                            getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT));
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -506,7 +508,7 @@
     }
 
     protected LIRKind getPhiKind(PhiNode phi) {
-        return gen.getLIRKind(phi.stamp());
+        return gen.getLIRKind(phi.stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -529,13 +531,13 @@
     }
 
     private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        LIRKind kind = gen.getLIRKind(node.getValue().stamp());
+        LIRKind kind = gen.getLIRKind(node.getValue().stamp(NodeView.DEFAULT));
         Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
         gen.emitCompareBranch(kind.getPlatformKind(), operand(node.getValue()), nullValue, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
-        PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
+        PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
         gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
     }
 
@@ -558,12 +560,12 @@
     public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) {
         if (node instanceof IsNullNode) {
             IsNullNode isNullNode = (IsNullNode) node;
-            LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp());
+            LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp(NodeView.DEFAULT));
             Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
             return gen.emitConditionalMove(kind.getPlatformKind(), operand(isNullNode.getValue()), nullValue, Condition.EQ, false, trueValue, falseValue);
         } else if (node instanceof CompareNode) {
             CompareNode compare = (CompareNode) node;
-            PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
+            PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
             return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
         } else if (node instanceof LogicConstantNode) {
             return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
@@ -579,7 +581,8 @@
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
         FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
-        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
+        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess()),
+                        callTarget.signature(), gen);
         frameMapBuilder.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
@@ -650,7 +653,7 @@
             if (keyCount == 1) {
                 assert defaultTarget != null;
                 double probability = x.probability(x.keySuccessor(0));
-                LIRKind kind = gen.getLIRKind(x.value().stamp());
+                LIRKind kind = gen.getLIRKind(x.value().stamp(NodeView.DEFAULT));
                 Value key = gen.emitConstant(kind, x.keyAt(0));
                 gen.emitCompareBranch(kind.getPlatformKind(), gen.load(operand(x.value())), key, Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
             } else if (x instanceof IntegerSwitchNode && x.isSorted()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/VersionsTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2013, 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.debug.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashMap;
+import java.util.Map;
+import org.graalvm.compiler.debug.Versions;
+import org.junit.After;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+import org.junit.Test;
+
+public class VersionsTest {
+    private File temporaryDirectory;
+
+    @After
+    public void cleanUp() throws IOException {
+        if (temporaryDirectory != null) {
+            Files.walkFileTree(temporaryDirectory.toPath(), new FileVisitor<Path>() {
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                    Files.delete(dir);
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+        temporaryDirectory = null;
+    }
+
+    @Test
+    public void emptyProperties() {
+        Path root = Paths.get("file:/");
+        Versions v = new Versions(root);
+        assertEmpty(v.withVersions(null));
+    }
+
+    @Test
+    public void emptyWithNullProperties() {
+        Path root = Paths.get("file:/");
+        Versions v = new Versions(root);
+        assertEmpty(v.withVersions(null));
+    }
+
+    @Test
+    public void readFromSameDirNullProps() throws IOException {
+        File dir = prepareReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+        Map<Object, Object> map = v.withVersions(null);
+        assertNonModifiable(map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+    }
+
+    @Test
+    public void readFromSameDir() throws IOException {
+        File dir = prepareReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+
+        Map<Object, Object> prepared = new HashMap<>();
+        prepared.put("test", "best");
+
+        Map<Object, Object> map = v.withVersions(prepared);
+        assertSame(prepared, map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+        assertEquals("best", map.get("test"));
+    }
+
+    @Test
+    public void readFromSubDirNullProps() throws IOException {
+        File dir = prepareSubReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+        Map<Object, Object> map = v.withVersions(null);
+        assertNonModifiable(map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+    }
+
+    @Test
+    public void readFromSubDir() throws IOException {
+        File dir = prepareSubReleaseFile();
+
+        Versions v = new Versions(dir.toPath());
+
+        Map<Object, Object> prepared = new HashMap<>();
+        prepared.put("test", "best");
+
+        Map<Object, Object> map = v.withVersions(prepared);
+        assertSame(prepared, map);
+
+        assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
+        assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
+        assertEquals("best", map.get("test"));
+    }
+
+    private File prepareReleaseFile() throws IOException {
+        if (temporaryDirectory == null) {
+            temporaryDirectory = File.createTempFile("versions", ".tmp");
+            temporaryDirectory.delete();
+            assumeTrue(temporaryDirectory.mkdirs());
+            try (FileWriter w = new FileWriter(new File(temporaryDirectory, "release"))) {
+// @formatter:off
+                w.write(
+"OS_NAME=linux\n" +
+"OS_ARCH=amd64\n" +
+"SOURCE=\" truffle:16055f1ffaf736b7b86dcfaea53971983cd9ae0a sdk:16055f1ffaf736b7b86dcfaea53971983cd9ae0a " +
+"tools-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-js:d374a8fd2733487a9f7518be6a55eb6163a779d1 " +
+"graal-nodejs:3fcaf6874c9059d5ca5f0615edaa405d66cc1b02 truffleruby:7930979c3b0af09a910accaaf3e73b2a55d2bade " +
+"fastr:079c6513b46f36abc24bce8aa6022c90576b3eaf graalpython:4cbee7853d460930c4d693970a21b73f811a4703 " +
+"sulong:2c425f92caa004b12f60428a3e7e6e2715b51f87 substratevm:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
+"compiler:16055f1ffaf736b7b86dcfaea53971983cd9ae0a substratevm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
+"vm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 \"\n" +
+"COMMIT_INFO={\"vm-enterprise\":{\"commit.rev\":\"fcc1292a05e807a63589e24ce6073aafdef45bb9\"," +
+"\"commit.committer\":\"Vojin Jovanovic <vojin.jovanovic@oracle.com>\",}}\n" +
+"GRAALVM_VERSION=\"0.29-dev\""
+                );
+// @formatter:on
+            }
+        }
+        return temporaryDirectory;
+    }
+
+    private File prepareSubReleaseFile() throws IOException {
+        File subdir = new File(prepareReleaseFile(), "subdir");
+        assumeTrue(subdir.mkdirs());
+        return subdir;
+    }
+
+    private static void assertEmpty(Map<?, ?> map) {
+        assertNotNull(map);
+        assertTrue(map.isEmpty());
+        assertNonModifiable(map);
+    }
+
+    private static void assertNonModifiable(Map<?, ?> map) {
+        try {
+            map.put(null, null);
+            fail("Map shall not be modifiable: " + map);
+        } catch (UnsupportedOperationException ex) {
+            // ok
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Fri Dec 01 11:17:45 2017 -0800
@@ -130,6 +130,20 @@
     }
 
     /**
+     * Adds version properties to the provided map. The version properties are read at a start of
+     * the JVM from a JVM specific location. Each property identifiers a commit of a certain
+     * component in the system. The properties added to the {@code properties} map are prefixed with
+     * {@code "version."} prefix.
+     *
+     * @param properties map to add the version properties to or {@code null}
+     * @return {@code properties} with version properties added or an unmodifiable map containing
+     *         the version properties if {@code properties == null}
+     */
+    public static Map<Object, Object> addVersionProperties(Map<Object, Object> properties) {
+        return Versions.VERSIONS.withVersions(properties);
+    }
+
+    /**
      * The immutable configuration that can be shared between {@link DebugContext} objects.
      */
     static final class Immutable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Versions.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.debug;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Avoid using directly. Only public for the needs of unit testing. */
+public final class Versions {
+    static final Versions VERSIONS;
+    static {
+        String home = System.getProperty("java.home");
+        VERSIONS = new Versions(home == null ? null : new File(home).toPath());
+    }
+
+    private final Map<Object, Object> versions;
+
+    public Versions(Path home) {
+        Map<Object, Object> map = new HashMap<>();
+        ASSIGN: try {
+            Path info = findReleaseInfo(home);
+            if (info == null) {
+                break ASSIGN;
+            }
+            for (String line : Files.readAllLines(info)) {
+                final String prefix = "SOURCE=";
+                if (line.startsWith(prefix)) {
+                    for (String versionInfo : line.substring(prefix.length()).replace('"', ' ').split(" ")) {
+                        String[] idVersion = versionInfo.split(":");
+                        if (idVersion != null && idVersion.length == 2) {
+                            map.put("version." + idVersion[0], idVersion[1]);
+                        }
+                    }
+                    break ASSIGN;
+                }
+            }
+        } catch (IOException ex) {
+            // no versions file found
+        }
+        versions = Collections.unmodifiableMap(map);
+    }
+
+    public Map<Object, Object> withVersions(Map<Object, Object> properties) {
+        if (properties == null) {
+            return versions;
+        } else {
+            properties.putAll(versions);
+            return properties;
+        }
+    }
+
+    private static Path findReleaseInfo(Path jreDir) {
+        if (jreDir == null) {
+            return null;
+        }
+        Path releaseInJre = jreDir.resolve("release");
+        if (Files.exists(releaseInJre)) {
+            return releaseInJre;
+        }
+        Path jdkDir = jreDir.getParent();
+        if (jdkDir == null) {
+            return null;
+        }
+        Path releaseInJdk = jdkDir.resolve("release");
+        return Files.exists(releaseInJdk) ? releaseInJdk : null;
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -110,7 +111,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -181,7 +182,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/DataPatchInConstantsTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/DataPatchInConstantsTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
@@ -170,7 +171,7 @@
         @Input protected ValueNode input;
 
         protected LoadThroughPatchNode(ValueNode input) {
-            super(TYPE, input.stamp());
+            super(TYPE, input.stamp(NodeView.DEFAULT));
             this.input = input;
         }
 
@@ -179,9 +180,9 @@
             assert input.isConstant();
 
             LIRGeneratorTool gen = generator.getLIRGeneratorTool();
-            Variable ret = gen.newVariable(gen.getLIRKind(stamp()));
+            Variable ret = gen.newVariable(gen.getLIRKind(stamp(NodeView.DEFAULT)));
 
-            gen.append(new LoadThroughPatchOp(input.asConstant(), stamp() instanceof NarrowOopStamp, ret));
+            gen.append(new LoadThroughPatchOp(input.asConstant(), stamp(NodeView.DEFAULT) instanceof NarrowOopStamp, ret));
             generator.setResult(this, ret);
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Fri Dec 01 11:17:45 2017 -0800
@@ -43,6 +43,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
@@ -76,7 +77,7 @@
 
         @Override
         public void generate(NodeLIRBuilderTool generator) {
-            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+            LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
             generator.setResult(this, heapBaseRegister.asValue(kind));
         }
     }
@@ -117,11 +118,6 @@
         return false;
     }
 
-    @Override
-    protected boolean mightBeOptimized(ValueNode value) {
-        return super.mightBeOptimized(value) || value instanceof CompressionNode;
-    }
-
     private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
         if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
             return false;
@@ -134,7 +130,7 @@
         }
 
         if (heapBaseRegister != null && encoding.getBase() == heapBase) {
-            if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
+            if ((!generatePIC || compression.stamp(NodeView.DEFAULT) instanceof ObjectStamp) && other == null) {
                 // With PIC it is only legal to do for oops since the base value may be
                 // different at runtime.
                 ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
@@ -142,7 +138,7 @@
             } else {
                 return false;
             }
-        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
+        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp(NodeView.DEFAULT) instanceof KlassPointerStamp)) {
             if (generatePIC) {
                 if (other == null) {
                     ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -113,7 +114,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
+            assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
             setResult(param, gen.emitMove(paramValue));
         }
     }
@@ -187,7 +188,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodes.DirectCallTargetNode;
 import org.graalvm.compiler.nodes.FullInfopointNode;
 import org.graalvm.compiler.nodes.IndirectCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -158,7 +159,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
+            sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -22,14 +22,15 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
-
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -41,10 +42,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import jdk.vm.ci.aarch64.AArch64;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
+import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
 
 /**
  * use
@@ -55,7 +54,7 @@
  *
  * to print disassembly.
  */
-public class AheadOfTimeCompilationTest extends GraalCompilerTest {
+public class AheadOfTimeCompilationTest extends HotSpotGraalCompilerTest {
 
     public static final Object STATICFINALOBJECT = new Object();
     public static final String STATICFINALSTRING = "test string";
@@ -74,9 +73,10 @@
     public void testStaticFinalObjectAOT() {
         StructuredGraph result = compile("getStaticFinalObject", true);
         assertDeepEquals(1, getConstantNodes(result).count());
-        Stamp constantStamp = getConstantNodes(result).first().stamp();
+        Stamp constantStamp = getConstantNodes(result).first().stamp(NodeView.DEFAULT);
         Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp);
-        assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
@@ -99,8 +99,8 @@
         assertDeepEquals(1, filter.count());
         HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
         assertDeepEquals(type.klass(), filter.first().asConstant());
-
-        assertDeepEquals(1, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 2 : 1;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
@@ -124,10 +124,10 @@
         StructuredGraph result = compile("getPrimitiveClassObject", true);
         NodeIterable<ConstantNode> filter = getConstantNodes(result);
         assertDeepEquals(1, filter.count());
-        Stamp constantStamp = filter.first().stamp();
+        Stamp constantStamp = filter.first().stamp(NodeView.DEFAULT);
         Assert.assertTrue(constantStamp instanceof KlassPointerStamp);
-
-        assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
+        int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
+        assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Fri Dec 01 11:17:45 2017 -0800
@@ -143,50 +143,49 @@
     }
 
     static {
+        // These are dead
         add(IGNORE,
-                        // dead
                         "java/lang/Math.atan2(DD)D",
-                        // Used during stack walking
-                        "java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;",
-                        // Marker intrinsic id
-                        "java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
-                        // Marker intrinsic id
-                        "java/lang/invoke/MethodHandle.invoke*",
-                        // Implemented through lowering
-                        "java/lang/ref/Reference.get()Ljava/lang/Object;",
-                        // Used during stack walk
-                        "java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;",
-                        // Only used by C1
-                        "java/nio/Buffer.checkIndex(I)I",
-                        // dead
+                        "jdk/internal/misc/Unsafe.park(ZJ)V",
+                        "jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
                         "sun/misc/Unsafe.park(ZJ)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchRead(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchReadStatic(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchWrite(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.prefetchWriteStatic(Ljava/lang/Object;J)V",
-                        // dead
                         "sun/misc/Unsafe.unpark(Ljava/lang/Object;)V");
 
-        add(TO_BE_INVESTIGATED,
-                        // JDK 8
-                        "java/lang/Double.doubleToLongBits(D)J",
-                        "java/lang/Float.floatToIntBits(F)I",
+        // These only exist to assist escape analysis in C2
+        add(IGNORE,
+                        "java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;");
+
+        // These are only used for the security handling during stack walking
+        add(IGNORE,
+                        "java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
+
+        // These are marker intrinsic ids only
+        add(IGNORE,
+                        "java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
+                        "java/lang/invoke/MethodHandle.invoke*");
+
+        // These are implemented through lowering
+        add(IGNORE,
+                        "java/lang/ref/Reference.get()Ljava/lang/Object;");
+
+        // These are only used by C1
+        add(IGNORE,
+                        "java/nio/Buffer.checkIndex(I)I");
+
+        // These do general compiler optimizations and convert min/max to cmov instructions. We are
+        // ignoring them as cmovs are not necessarily beneficial.
+        add(IGNORE,
+                        "java/lang/Math.max(II)I",
+                        "java/lang/Math.min(II)I");
+
+        // These are known to be implemented down stream
+        add(IGNORE,
                         "java/lang/Integer.toString(I)Ljava/lang/String;",
-                        "java/lang/Math.decrementExact(I)I",
-                        "java/lang/Math.decrementExact(J)J",
-                        "java/lang/Math.incrementExact(I)I",
-                        "java/lang/Math.incrementExact(J)J",
-                        "java/lang/Math.max(II)I",
-                        "java/lang/Math.min(II)I",
-                        "java/lang/Math.negateExact(I)I",
-                        "java/lang/Math.negateExact(J)J",
                         "java/lang/String.<init>(Ljava/lang/String;)V",
-                        "java/lang/String.compareTo(Ljava/lang/String;)I",
-                        "java/lang/String.indexOf(Ljava/lang/String;)I",
                         "java/lang/StringBuffer.<init>()V",
                         "java/lang/StringBuffer.<init>(I)V",
                         "java/lang/StringBuffer.<init>(Ljava/lang/String;)V",
@@ -201,172 +200,11 @@
                         "java/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;",
                         "java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
                         "java/lang/StringBuilder.toString()Ljava/lang/String;",
-                        "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
                         "java/util/Arrays.copyOf([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;",
-                        "java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;",
-                        "oracle/jrockit/jfr/Timing.counterTime()J",
-                        "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
-                        "oracle/jrockit/jfr/VMJFR.threadID()I",
-                        "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
-                        "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I",
-                        "sun/security/provider/SHA.implCompress([BI)V",
-                        "sun/security/provider/SHA2.implCompress([BI)V",
-                        "sun/security/provider/SHA5.implCompress([BI)V");
+                        "java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;");
 
-        add(TO_BE_INVESTIGATED,
-                        // JDK 9
-                        "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
-                        "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
-                        "java/lang/Math.fma(DDD)D",
-                        "java/lang/Math.fma(FFF)F",
-                        "java/lang/Object.notify()V",
-                        "java/lang/Object.notifyAll()V",
-                        "java/lang/StringCoding.hasNegatives([BII)Z",
-                        "java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
-                        "java/lang/StringLatin1.compareTo([B[B)I",
-                        "java/lang/StringLatin1.compareToUTF16([B[B)I",
-                        "java/lang/StringLatin1.equals([B[B)Z",
-                        "java/lang/StringLatin1.indexOf([BI[BII)I",
-                        "java/lang/StringLatin1.indexOf([B[B)I",
-                        "java/lang/StringLatin1.inflate([BI[BII)V",
-                        "java/lang/StringLatin1.inflate([BI[CII)V",
-                        "java/lang/StringUTF16.compareTo([B[B)I",
-                        "java/lang/StringUTF16.compareToLatin1([B[B)I",
-                        "java/lang/StringUTF16.compress([BI[BII)I",
-                        "java/lang/StringUTF16.compress([CI[BII)I",
-                        "java/lang/StringUTF16.equals([B[B)Z",
-                        "java/lang/StringUTF16.getChar([BI)C",
-                        "java/lang/StringUTF16.getChars([BII[CI)V",
-                        "java/lang/StringUTF16.indexOf([BI[BII)I",
-                        "java/lang/StringUTF16.indexOf([B[B)I",
-                        "java/lang/StringUTF16.indexOfChar([BIII)I",
-                        "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
-                        "java/lang/StringUTF16.indexOfLatin1([B[B)I",
-                        "java/lang/StringUTF16.putChar([BII)V",
-                        "java/lang/StringUTF16.toBytes([CII)[B",
-                        "java/lang/Thread.onSpinWait()V",
-                        "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
-                        "java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I",
-                        "java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I",
-                        "java/math/BigInteger.implMulAdd([I[IIII)I",
-                        "java/math/BigInteger.implSquareToLen([II[II)[I",
-                        "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
-                        "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
-                        "java/util/zip/Adler32.updateByteBuffer(IJII)I",
-                        "java/util/zip/Adler32.updateBytes(I[BII)I",
-                        "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
-                        "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
-                        "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
-                        "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
-                        "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
-                        "jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
-                        "jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
-                        "jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
-                        "jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
-                        "jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
-                        "jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
-                        "jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
-                        "jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
-                        "jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
-                        "jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
-                        "jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
-                        "jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
-                        "jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
-                        "jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
-                        "jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
-                        "jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
-                        "jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
-                        "jdk/internal/misc/Unsafe.park(ZJ)V",
-                        "jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
-                        "jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
-                        "jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
-                        "jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
-                        "jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
-                        "jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
-                        "jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
-                        "jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
-                        "jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
-                        "jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z",
-                        "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
-                        "jdk/jfr/internal/JVM.counterTime()J",
-                        "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
-                        "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J",
-                        "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
-                        "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I",
-                        "sun/security/provider/SHA.implCompress0([BI)V",
-                        "sun/security/provider/SHA2.implCompress0([BI)V",
-                        "sun/security/provider/SHA5.implCompress0([BI)V");
-
-        if (!getHostArchitectureName().equals("amd64")) {
-            add(TO_BE_INVESTIGATED,
-                            // Can we implement these on non-AMD64 platforms? C2 seems to.
-                            "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
-                            "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
-                            "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
-                            "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
-                            "sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
-            // JDK 9
-            add(TO_BE_INVESTIGATED,
-                            "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
-                            "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
-                            "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
-                            "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
-                            "jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
-                            "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
-                            "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
-                            "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
-                            "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
-                            "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
-                            "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
-                            "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
-                            "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
-        }
-
-        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
-        GraalHotSpotVMConfig config = rt.getVMConfig();
-
-        /*
-         * These are known to be implemented but the platform dependent conditions for when they are
-         * enabled are complex so just ignore them all the time.
-         */
+        // These are known to be implemented but the platform dependent conditions
+        // for when they are enabled are complex so just ignore them all the time.
         add(IGNORE,
                         "java/lang/Integer.bitCount(I)I",
                         "java/lang/Integer.numberOfLeadingZeros(I)I",
@@ -375,52 +213,323 @@
                         "java/lang/Long.numberOfLeadingZeros(J)I",
                         "java/lang/Long.numberOfTrailingZeros(J)I");
 
+        // Relevant for Java flight recorder
+        add(TO_BE_INVESTIGATED,
+                        "oracle/jrockit/jfr/Timing.counterTime()J",
+                        "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
+                        "oracle/jrockit/jfr/VMJFR.threadID()I");
+
+        add(TO_BE_INVESTIGATED,
+                        // Should be fairly easy to implement - C2 intrinsifies these to use "v !=
+                        // v" to check for NaN instead of looking at the bit pattern.
+                        "java/lang/Double.doubleToLongBits(D)J",
+                        "java/lang/Float.floatToIntBits(F)I",
+
+                        // Should be trivial to implement because we already have existing nodes
+                        "java/lang/Math.decrementExact(I)I",
+                        "java/lang/Math.decrementExact(J)J",
+                        "java/lang/Math.incrementExact(I)I",
+                        "java/lang/Math.incrementExact(J)J",
+
+                        // Similar to addExact
+                        "java/lang/Math.negateExact(I)I",
+                        // Similar to addExact
+                        "java/lang/Math.negateExact(J)J",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "java/lang/String.compareTo(Ljava/lang/String;)I",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "java/lang/String.indexOf(Ljava/lang/String;)I",
+                        // Can share most implementation parts with with
+                        // Unsafe.allocateUninitializedArray0
+                        "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
+                        // HotSpot MacroAssembler-based intrinsic
+                        "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
+                        // Stub based intrinsics but implementation seems complex in C2
+                        "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I");
+
+        if (isJDK9OrHigher()) {
+            // Relevant for Java flight recorder
+            add(TO_BE_INVESTIGATED,
+                            "jdk/jfr/internal/JVM.counterTime()J",
+                            "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
+                            "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
+
+            add(TO_BE_INVESTIGATED,
+                            // Some logic and a stub call
+                            "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
+                            // Stub and very little logic
+                            "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "java/lang/Math.fma(DDD)D",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "java/lang/Math.fma(FFF)F",
+                            // Just a runtime call (the called C code has a better fast path)
+                            "java/lang/Object.notify()V",
+                            // Just a runtime call (the called C code has a better fast path)
+                            "java/lang/Object.notifyAll()V",
+                            // Emit pause instruction if os::is_MP()
+                            "java/lang/Thread.onSpinWait()V",
+                            // Just check if the argument is a compile time constant
+                            "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
+                            // Some logic and a runtime call
+                            "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
+                            // Only used as a marker for vectorization?
+                            "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
+                            // Only implemented on non-AMD64 platforms (some logic and runtime call)
+                            "java/util/zip/Adler32.updateByteBuffer(IJII)I",
+                            // Only implemented on non-AMD64 platforms (some logic and runtime call)
+                            "java/util/zip/Adler32.updateBytes(I[BII)I",
+                            // similar to CRC32.updateBytes
+                            "java/util/zip/CRC32C.updateBytes(I[BII)I",
+                            // similar to CRC32.updateDirectByteBuffer
+                            "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I",
+                            // Emits a slow and a fast path and some dispatching logic
+                            "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
+
+                            // Should be easy to implement as it seems to match the logic that is
+                            // already implemented in ValueCompareAndSwapNode. On the high-level, we
+                            // would need something similar to UnsafeCompareAndSwapNode but with a
+                            // different result type.
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int, long, and Object.
+                            "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int and long.
+                            "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
+                            "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
+
+                            // Should be easy to implement as we already have an implementation for
+                            // int, long, and Object.
+                            "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
+                            "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
+
+                            // Control flow, deopts, and a cast
+                            "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
+                            // HotSpot MacroAssembler-based intrinsic
+                            "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
+                            // Runtime call and some complex compiler logic
+                            "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
+            /*
+             * Per default, all these operations are mapped to some generic method for which we
+             * already have compiler intrinsics. Performance-wise it would be better to support them
+             * explicitly as the more generic method might be more restrictive and therefore slower
+             * than necessary.
+             */
+            add(TO_BE_INVESTIGATED,
+                            // Mapped to compareAndExchange*
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
+                            "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
+
+                            // Mapped to get*Volatile
+                            "jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
+                            "jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
+                            "jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
+                            "jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
+                            "jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
+                            "jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
+                            "jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
+                            "jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
+                            "jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
+                            "jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
+                            "jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
+                            "jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
+                            "jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
+                            "jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
+                            "jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
+                            "jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
+                            "jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
+
+                            // Mapped to put*Volatile
+                            "jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
+                            "jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
+                            "jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
+                            "jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
+                            "jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
+                            "jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
+                            "jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
+                            "jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
+                            "jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
+
+                            // Mapped to compareAndSet*
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
+                            "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z");
+
+            // Compact string support - HotSpot MacroAssembler-based intrinsic or complex C2 logic.
+            add(TO_BE_INVESTIGATED,
+                            "java/lang/StringCoding.hasNegatives([BII)Z",
+                            "java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
+                            "java/lang/StringLatin1.compareTo([B[B)I",
+                            "java/lang/StringLatin1.compareToUTF16([B[B)I",
+                            "java/lang/StringLatin1.equals([B[B)Z",
+                            "java/lang/StringLatin1.indexOf([BI[BII)I",
+                            "java/lang/StringLatin1.indexOf([B[B)I",
+                            "java/lang/StringLatin1.inflate([BI[BII)V",
+                            "java/lang/StringLatin1.inflate([BI[CII)V",
+                            "java/lang/StringUTF16.compareTo([B[B)I",
+                            "java/lang/StringUTF16.compareToLatin1([B[B)I",
+                            "java/lang/StringUTF16.compress([BI[BII)I",
+                            "java/lang/StringUTF16.compress([CI[BII)I",
+                            "java/lang/StringUTF16.equals([B[B)Z",
+                            "java/lang/StringUTF16.getChar([BI)C",
+                            "java/lang/StringUTF16.getChars([BII[CI)V",
+                            "java/lang/StringUTF16.indexOf([BI[BII)I",
+                            "java/lang/StringUTF16.indexOf([B[B)I",
+                            "java/lang/StringUTF16.indexOfChar([BIII)I",
+                            "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
+                            "java/lang/StringUTF16.indexOfLatin1([B[B)I",
+                            "java/lang/StringUTF16.putChar([BII)V",
+                            "java/lang/StringUTF16.toBytes([CII)[B");
+        }
+
+        if (!getHostArchitectureName().equals("amd64")) {
+            // Can we implement these on non-AMD64 platforms? C2 seems to.
+            add(TO_BE_INVESTIGATED,
+                            "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
+                            "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
+                            "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
+                            "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
+                            "sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
+
+            if (isJDK9OrHigher()) {
+                add(TO_BE_INVESTIGATED,
+                                "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
+                                "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
+                                "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
+                                "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
+                                "jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
+                                "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
+                                "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
+                                "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
+                                "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
+                                "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
+                                "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
+                                "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
+                                "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
+            }
+        }
+
+        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
+        GraalHotSpotVMConfig config = rt.getVMConfig();
+
+        /*
+         * The intrinsics down here are known to be implemented but they are not always enabled on
+         * the HotSpot side (e.g., because they require certain CPU features). So, we are ignoring
+         * them if the HotSpot config tells us that they can't be used.
+         */
+
+        // CRC32 intrinsics
         if (!config.useCRC32Intrinsics) {
-            // Registration of the CRC32 plugins is guarded by UseCRC32Intrinsics
             add(IGNORE, "java/util/zip/CRC32.update(II)I");
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE,
+                                "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
+                                "java/util/zip/CRC32.updateBytes0(I[BII)I");
+            } else {
                 add(IGNORE,
                                 "java/util/zip/CRC32.updateByteBuffer(IJII)I",
                                 "java/util/zip/CRC32.updateBytes(I[BII)I");
-            } else {
-                add(IGNORE,
-                                "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
-                                "java/util/zip/CRC32.updateBytes0(I[BII)I",
-                                "java/util/zip/CRC32C.updateBytes(I[BII)I",
-                                "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
-            }
-        } else {
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) {
-                add(TO_BE_INVESTIGATED,
-                                "java/util/zip/CRC32C.updateBytes(I[BII)I",
-                                "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
             }
         }
 
+        // AES intrinsics
         if (!config.useAESIntrinsics) {
-            // Registration of the AES plugins is guarded by UseAESIntrinsics
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE,
+                                "com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
+                                "com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
+                                "com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
+                                "com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
+            } else {
                 add(IGNORE,
                                 "com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V",
                                 "com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V",
                                 "com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I",
                                 "com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I");
-            } else {
-                add(IGNORE,
-                                "com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
-                                "com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
-                                "com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
-                                "com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
             }
         }
+
+        // BigInteger intrinsics
         if (!config.useMultiplyToLenIntrinsic()) {
-            // Registration of the AES plugins is guarded by UseAESIntrinsics
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
+            } else {
                 add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
-            } else {
-                add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
             }
         }
+        if (!config.useMulAddIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMulAdd([I[IIII)I");
+        }
+        if (!config.useMontgomeryMultiplyIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I");
+        }
+        if (!config.useMontgomerySquareIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I");
+        }
+        if (!config.useSquareToLenIntrinsic()) {
+            add(IGNORE, "java/math/BigInteger.implSquareToLen([II[II)[I");
+        }
+
+        // SHA intrinsics
+        if (!config.useSHA1Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA.implCompress0([BI)V");
+            } else {
+                add(IGNORE, "sun/security/provider/SHA.implCompress([BI)V");
+            }
+        }
+        if (!config.useSHA256Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA2.implCompress0([BI)V");
+            } else {
+                add(IGNORE, "sun/security/provider/SHA2.implCompress([BI)V");
+            }
+        }
+        if (!config.useSHA512Intrinsics()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "sun/security/provider/SHA5.implCompress0([BI)V");
+            } else {
+                add(IGNORE, "sun/security/provider/SHA5.implCompress([BI)V");
+            }
+        }
+    }
+
+    private static boolean isJDK9OrHigher() {
+        return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
     }
 
     private static String getHostArchitectureName() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -106,7 +106,12 @@
         final int maxProblems = 4;
         Probe[] probes = {
                         new Probe("To capture more information for diagnosing or reporting a compilation", maxProblems),
-                        new Probe("Retrying compilation of", maxProblems),
+                        new Probe("Retrying compilation of", maxProblems) {
+                            @Override
+                            String test() {
+                                return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
+                            }
+                        },
                         new Probe("adjusting CompilationFailureAction from Diagnose to Print", 1),
                         new Probe("adjusting CompilationFailureAction from Print to Silent", 1),
         };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.test;
+
+import java.util.function.Function;
+
+import org.graalvm.compiler.test.GraalTest;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.code.stack.InspectedFrame;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Create a single object which is referenced from a local, the expression stack and the lock state
+ * and then ensure that identity is maintained when the frame is forced to be materialized by
+ * {@link InspectedFrame#materializeVirtualObjects(boolean)}.
+ */
+public class HotSpotStackIntrospectionTest extends HotSpotGraalCompilerTest {
+
+    static StackIntrospection stackIntrospection = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getStackIntrospection();
+    static volatile int v;
+
+    public static void testSynchronizedSnippet(Function<Void, Void> f) {
+        Object a = new Object();
+        synchronized (a) {
+            testOnStack(a, forceFrameState(a, f), a);
+            // This object should be locked so try to notify on it
+            a.notify();
+        }
+    }
+
+    public static void testSnippet(Function<Void, Void> f) {
+        Object a = new Object();
+        testOnStack(a, forceFrameState(a, f), a);
+    }
+
+    private static void testOnStack(Object a, Object a2, Object a3) {
+        if (a != a2 || a != a3) {
+            throw new InternalError();
+        }
+    }
+
+    private static Object forceFrameState(Object a, Function<Void, Void> f) {
+        // Use a volatile store to ensure a FrameState is captured after this point.
+        v++;
+        f.apply(null);
+        return a;
+    }
+
+    @Test(timeout = 20000)
+    public void run() throws InvalidInstalledCodeException {
+        // The JDK9 bits are currently broken
+        Assume.assumeTrue(GraalTest.Java8OrEarlier);
+        test("testSnippet");
+    }
+
+    @Test(timeout = 20000)
+    public void runSynchronized() throws InvalidInstalledCodeException {
+        // The JDK9 bits are currently broken
+        Assume.assumeTrue(GraalTest.Java8OrEarlier);
+        test("testSynchronizedSnippet");
+    }
+
+    private void test(String name) throws InvalidInstalledCodeException {
+        ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(name));
+        Function<Void, Void> f = o -> {
+            stackIntrospection.iterateFrames(null, null, 0, frame -> {
+                if (frame.getMethod().equals(method)) {
+                    frame.materializeVirtualObjects(true);
+                }
+                return null;
+            });
+            return null;
+        };
+        InstalledCode code = getCode(method);
+        code.executeVarargs(f);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotUnsafeSubstitutionTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
+import org.graalvm.compiler.hotspot.meta.HotSpotUnsafeSubstitutions;
 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
 import org.junit.Test;
 
@@ -56,7 +57,7 @@
 
     @Test
     public void testUnsafeSubstitutions() throws Exception {
-        testGraph("unsafeCopyMemory");
+        testGraph("unsafeCopyMemory", HotSpotUnsafeSubstitutions.copyMemoryName);
     }
 
     public void unsafeCopyMemory(Object srcBase, long srcOffset, Object dstBase, long dstOffset, long bytes) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Fri Dec 01 11:17:45 2017 -0800
@@ -103,6 +103,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoweredCallTargetNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.SafepointNode;
 import org.graalvm.compiler.nodes.StartNode;
@@ -254,7 +255,7 @@
                 instanceofSnippets.lower(instanceOfDynamicNode, tool);
             } else {
                 ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
-                if (mirror.stamp().getStackKind() == JavaKind.Object) {
+                if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
                     ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
                     instanceOfDynamicNode.setMirror(classGetHub);
                 }
@@ -409,7 +410,7 @@
         StructuredGraph graph = n.graph();
         assert !n.getHub().isConstant();
         AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset);
-        n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(), null, BarrierType.NONE)));
+        n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)));
     }
 
     private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) {
@@ -422,11 +423,12 @@
         StructuredGraph graph = n.graph();
         assert !hub.isConstant() || GraalOptions.ImmutableCode.getValue(graph.getOptions());
         AddressNode mirrorAddress = createOffsetAddress(graph, hub, vmConfig.classMirrorOffset);
-        FloatingReadNode read = graph.unique(new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(),
-                        null, BarrierType.NONE));
+        FloatingReadNode read = graph.unique(
+                        new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(NodeView.DEFAULT),
+                                        null, BarrierType.NONE));
         if (vmConfig.classMirrorIsHandle) {
             AddressNode address = createOffsetAddress(graph, read, 0);
-            read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(), null, BarrierType.NONE));
+            read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
         }
         n.replaceAtUsagesAndDelete(read);
     }
@@ -439,7 +441,7 @@
         StructuredGraph graph = n.graph();
         assert !n.getValue().isConstant();
         AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getVMConfig().klassOffset);
-        FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(), null, BarrierType.NONE));
+        FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
         n.replaceAtUsagesAndDelete(read);
     }
 
@@ -448,7 +450,7 @@
             MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
             NodeInputList<ValueNode> parameters = callTarget.arguments();
             ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
-            if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
+            if (!callTarget.isStatic() && receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
                 ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool);
                 parameters.set(0, nonNullReceiver);
                 receiver = nonNullReceiver;
@@ -586,7 +588,7 @@
                 int size = osrLocal.getStackKind().getSlotCount();
                 int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize;
                 AddressNode address = createOffsetAddress(graph, buffer, offset);
-                ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(), BarrierType.NONE));
+                ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 osrLocal.replaceAndDelete(load);
                 graph.addBeforeFixed(migrationEnd, load);
             }
@@ -609,7 +611,7 @@
 
                 // load the displaced mark from the osr buffer
                 AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader);
-                ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(), BarrierType.NONE));
+                ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 graph.addBeforeFixed(migrationEnd, loadDisplacedHeader);
 
                 // we need to initialize the stack slot for the lock
@@ -623,7 +625,7 @@
 
                 // load the lock object from the osr buffer
                 AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject);
-                ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(), BarrierType.NONE));
+                ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
                 lock.replaceAndDelete(loadObject);
                 graph.addBeforeFixed(migrationEnd, loadObject);
             }
@@ -688,7 +690,7 @@
         }
 
         StructuredGraph graph = node.graph();
-        ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments()));
+        ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
         graph.replaceFixedWithFixed(node, foreignCallNode);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri Dec 01 11:17:45 2017 -0800
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -318,7 +319,7 @@
     private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
         ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
         int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
-        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
+        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long), NodeView.DEFAULT), b.add(ConstantNode.forInt(shift))));
         ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
         AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
         boolean notCompressible = false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvokeDynamicPlugin.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvokeDynamicPlugin.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -136,7 +137,7 @@
 
         ConstantNode appendixNode = ConstantNode.forConstant(appendix, builder.getMetaAccess(), builder.getGraph());
 
-        Stamp appendixStamp = appendixNode.stamp();
+        Stamp appendixStamp = appendixNode.stamp(NodeView.DEFAULT);
         Stamp resolveStamp = treatAppendixAsConstant ? appendixStamp : appendixStamp.unrestricted();
         ResolveDynamicConstantNode resolveNode = new ResolveDynamicConstantNode(resolveStamp, appendixNode);
         ResolveDynamicConstantNode added = builder.append(resolveNode);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSnippetReflectionProvider.java	Fri Dec 01 11:17:45 2017 -0800
@@ -87,7 +87,7 @@
         // Need to test all fields since there no guarantee under the JMM
         // about the order in which these fields are written.
         GraalHotSpotVMConfig config = runtime.getVMConfig();
-        if (configType == null || wordTypesType == null || configType == null) {
+        if (configType == null || wordTypesType == null || runtimeType == null) {
             wordTypesType = wordTypes.getClass();
             runtimeType = runtime.getClass();
             configType = config.getClass();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotWordOperationPlugin.java	Fri Dec 01 11:17:45 2017 -0800
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
 import org.graalvm.compiler.hotspot.word.PointerCastNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
 import org.graalvm.compiler.nodes.calc.IsNullNode;
@@ -102,23 +103,23 @@
                 HotspotOpcode opcode = operation.opcode();
                 ValueNode left = args[0];
                 ValueNode right = args[1];
-                assert left.stamp() instanceof MetaspacePointerStamp : left + " " + left.stamp();
-                assert right.stamp() instanceof MetaspacePointerStamp : right + " " + right.stamp();
+                assert left.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : left + " " + left.stamp(NodeView.DEFAULT);
+                assert right.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : right + " " + right.stamp(NodeView.DEFAULT);
                 assert opcode == POINTER_EQ || opcode == POINTER_NE;
 
                 PointerEqualsNode comparison = b.add(new PointerEqualsNode(left, right));
                 ValueNode eqValue = b.add(forBoolean(opcode == POINTER_EQ));
                 ValueNode neValue = b.add(forBoolean(opcode == POINTER_NE));
-                b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue));
+                b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue, NodeView.DEFAULT));
                 break;
 
             case IS_NULL:
                 assert args.length == 1;
                 ValueNode pointer = args[0];
-                assert pointer.stamp() instanceof MetaspacePointerStamp;
+                assert pointer.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp;
 
                 LogicNode isNull = b.addWithInputs(IsNullNode.create(pointer));
-                b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false))));
+                b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)), NodeView.DEFAULT));
                 break;
 
             case FROM_POINTER:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotCompressionNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/HotSpotCompressionNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
@@ -45,7 +46,7 @@
     public static final NodeClass<HotSpotCompressionNode> TYPE = NodeClass.create(HotSpotCompressionNode.class);
 
     public HotSpotCompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
-        super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(), encoding), encoding);
+        super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(NodeView.DEFAULT), encoding), encoding);
     }
 
     public static HotSpotCompressionNode compress(ValueNode input, CompressEncoding encoding) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -42,7 +43,7 @@
     @Input ValueNode value;
 
     public InitializeKlassNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/InitializeKlassStubCall.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@@ -61,7 +62,7 @@
     protected Constant constant;
 
     protected InitializeKlassStubCall(ValueNode value, ValueNode string) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyFixedNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.hotspot.word.MethodPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -56,14 +57,14 @@
     protected HotSpotConstantLoadAction action;
 
     public LoadConstantIndirectlyFixedNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public LoadConstantIndirectlyFixedNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -55,14 +56,14 @@
     protected HotSpotConstantLoadAction action;
 
     public LoadConstantIndirectlyNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public LoadConstantIndirectlyNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.constant = null;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -41,13 +42,13 @@
     protected HotSpotConstantLoadAction action;
 
     public ResolveConstantNode(ValueNode value, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.action = action;
     }
 
     public ResolveConstantNode(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -59,14 +60,14 @@
     protected HotSpotConstantLoadAction action;
 
     public ResolveConstantStubCall(ValueNode value, ValueNode string) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
         this.action = HotSpotConstantLoadAction.RESOLVE;
     }
 
     public ResolveConstantStubCall(ValueNode value, ValueNode string, HotSpotConstantLoadAction action) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
         this.string = string;
         this.action = action;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicStubCall.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -59,7 +60,7 @@
     protected Constant constant;
 
     public ResolveDynamicStubCall(ValueNode value) {
-        super(TYPE, value.stamp());
+        super(TYPE, value.stamp(NodeView.DEFAULT));
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -50,6 +50,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StartNode;
@@ -185,8 +186,8 @@
                  * (if a branch was not parsed for example). In cases when this is possible, we
                  * insert a guard and narrow the OSRLocal stamp at its usages.
                  */
-                Stamp narrowedStamp = proxy.value().stamp();
-                Stamp unrestrictedStamp = proxy.stamp().unrestricted();
+                Stamp narrowedStamp = proxy.value().stamp(NodeView.DEFAULT);
+                Stamp unrestrictedStamp = proxy.stamp(NodeView.DEFAULT).unrestricted();
                 ValueNode osrLocal;
                 if (i >= localsSize) {
                     osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -130,7 +131,7 @@
                 LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
                 random = loopRandomValueCache.get(loopBegin);
                 if (random == null) {
-                    PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(), loopBegin));
+                    PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(NodeView.DEFAULT), loopBegin));
                     phi.addInput(seed);
                     // X_{n+1} = a*X_n + c, using glibc-like constants
                     ValueNode a = ConstantNode.forInt(1103515245, graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConvertNode;
@@ -118,7 +119,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(), clazz);
+        return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(NodeView.DEFAULT), clazz);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Dec 01 11:17:45 2017 -0800
@@ -45,6 +45,7 @@
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
@@ -124,7 +125,7 @@
                     AddressNode address = access.getAddress();
                     if (address instanceof OffsetAddressNode) {
                         OffsetAddressNode offset = (OffsetAddressNode) address;
-                        assert offset.getBase().stamp().isCompatible(read.stamp());
+                        assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT));
                         return offset.getBase();
                     }
                 }
@@ -370,8 +371,8 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             ValueNode javaObject = findReadHub(object);
             if (javaObject != null) {
-                if (javaObject.stamp() instanceof ObjectStamp) {
-                    ObjectStamp stamp = (ObjectStamp) javaObject.stamp();
+                if (javaObject.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                    ObjectStamp stamp = (ObjectStamp) javaObject.stamp(NodeView.DEFAULT);
                     HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess());
                     if (type.isArray() && !type.getComponentType().isPrimitive()) {
                         int layout = type.layoutHelper();
@@ -437,7 +438,7 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             TypeReference constantType = StampTool.typeReferenceOrNull(object);
             if (constantType != null && constantType.isExact()) {
-                return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
+                return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
             }
             return read;
         }
@@ -448,7 +449,8 @@
         public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
             TypeReference constantType = StampTool.typeReferenceOrNull(object);
             if (constantType != null && constantType.isExact()) {
-                return ConstantNode.forConstant(read.stamp(), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(), tool.getMetaAccess());
+                return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(),
+                                tool.getMetaAccess());
             }
             return read;
         }
@@ -962,7 +964,7 @@
                         AssumptionResult<ResolvedJavaType> leafType = element.findLeafConcreteSubtype();
                         if (leafType != null && leafType.canRecordTo(assumptions)) {
                             leafType.recordTo(assumptions);
-                            return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
+                            return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
                         }
                     }
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -65,7 +66,7 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object.isConstant()) {
-            assert object.stamp() instanceof AbstractObjectStamp;
+            assert object.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
             JavaConstant c = (JavaConstant) object.asConstant();
             if (ImmutableCode.getValue(tool.getOptions())) {
                 return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/InstanceOfSnippets.java	Fri Dec 01 11:17:45 2017 -0800
@@ -53,6 +53,7 @@
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.SnippetAnchorNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -332,7 +333,7 @@
             } else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
                 ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
                 Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
-                assert ((ObjectStamp) isAssignable.getThisClass().stamp()).nonNull();
+                assert ((ObjectStamp) isAssignable.getThisClass().stamp(NodeView.DEFAULT)).nonNull();
                 args.add("thisClassNonNull", isAssignable.getThisClass());
                 args.add("otherClass", isAssignable.getOtherClass());
                 args.add("trueValue", replacer.trueValue);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/KlassLayoutHelperNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
@@ -83,7 +84,7 @@
     public boolean inferStamp() {
         if (klass instanceof LoadHubNode) {
             LoadHubNode hub = (LoadHubNode) klass;
-            Stamp hubStamp = hub.getValue().stamp();
+            Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
             if (hubStamp instanceof ObjectStamp) {
                 ObjectStamp objectStamp = (ObjectStamp) hubStamp;
                 ResolvedJavaType type = objectStamp.type();
@@ -108,7 +109,7 @@
         if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
-            return canonical(this, config, klass, stamp(), tool.getConstantReflection(), tool.getMetaAccess());
+            return canonical(this, config, klass, stamp(NodeView.DEFAULT), tool.getConstantReflection(), tool.getMetaAccess());
         }
     }
 
@@ -123,7 +124,7 @@
         }
         if (klass instanceof LoadHubNode) {
             LoadHubNode hub = (LoadHubNode) klass;
-            Stamp hubStamp = hub.getValue().stamp();
+            Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
             if (hubStamp instanceof ObjectStamp) {
                 ObjectStamp ostamp = (ObjectStamp) hubStamp;
                 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ostamp.type();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Fri Dec 01 11:17:45 2017 -0800
@@ -99,6 +99,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -736,7 +737,7 @@
             StructuredGraph graph = monitorenterNode.graph();
             checkBalancedMonitors(graph, tool);
 
-            assert ((ObjectStamp) monitorenterNode.object().stamp()).nonNull();
+            assert ((ObjectStamp) monitorenterNode.object().stamp(NodeView.DEFAULT)).nonNull();
 
             Arguments args;
             if (useFastLocking) {
@@ -781,7 +782,7 @@
         }
 
         public static boolean isTracingEnabledForType(ValueNode object) {
-            ResolvedJavaType type = StampTool.typeOrNull(object.stamp());
+            ResolvedJavaType type = StampTool.typeOrNull(object.stamp(NodeView.DEFAULT));
             String filter = TraceMonitorsTypeFilter.getValue(object.getOptions());
             if (filter == null) {
                 return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ObjectCloneNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -62,14 +63,14 @@
 
     @Override
     protected Stamp computeStamp(ValueNode object) {
-        if (getConcreteType(object.stamp()) != null) {
-            return AbstractPointerStamp.pointerNonNull(object.stamp());
+        if (getConcreteType(object.stamp(NodeView.DEFAULT)) != null) {
+            return AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         }
         /*
          * If this call can't be intrinsified don't report a non-null stamp, otherwise the stamp
          * would change when this is lowered back to an invoke and we might lose a null check.
          */
-        return AbstractPointerStamp.pointerMaybeNull(object.stamp());
+        return AbstractPointerStamp.pointerMaybeNull(object.stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -91,16 +92,16 @@
                     }
 
                     assert snippetGraph != null : "ObjectCloneSnippets should be installed";
-                    assert getConcreteType(stamp()) != null;
+                    assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                     return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
                 }
                 assert false : "unhandled array type " + type.getComponentType().getJavaKind();
             } else {
                 Assumptions assumptions = graph().getAssumptions();
-                type = getConcreteType(getObject().stamp());
+                type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
                 if (type != null) {
                     StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
-                    ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp())));
+                    ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
                     NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
                     newGraph.addAfterFixed(newGraph.start(), newInstance);
                     ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
@@ -111,12 +112,12 @@
                         newGraph.addBeforeFixed(returnNode, load);
                         newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
                     }
-                    assert getConcreteType(stamp()) != null;
+                    assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                     return lowerReplacement(newGraph, tool);
                 }
             }
         }
-        assert getConcreteType(stamp()) == null;
+        assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
         return null;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Fri Dec 01 11:17:45 2017 -0800
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
 import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode;
@@ -447,7 +448,7 @@
             }
 
             ValueNode expected = writeBarrierPre.getExpectedObject();
-            if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
             }
@@ -472,7 +473,7 @@
             }
 
             ValueNode expected = readBarrier.getExpectedObject();
-            if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
             }
@@ -503,7 +504,7 @@
             }
 
             ValueNode value = writeBarrierPost.getValue();
-            if (value.stamp() instanceof NarrowOopStamp) {
+            if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
                 assert oopEncoding != null;
                 value = HotSpotCompressionNode.uncompress(value, oopEncoding);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -143,7 +144,7 @@
         FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
         graph().addBeforeFixed(this, basePtr);
         Stamp wordStamp = StampFactory.forKind(runtime.getTarget().wordJavaKind);
-        ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph());
+        ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph(), NodeView.DEFAULT);
         int shift = CodeUtil.log2(getArrayIndexScale(elementKind));
         ValueNode scaledIndex = graph().unique(new LeftShiftNode(wordPos, ConstantNode.forInt(shift, graph())));
         ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerStamp(wordStamp, getArrayBaseOffset(elementKind), graph())));
@@ -160,8 +161,8 @@
             ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
             ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
             ValueNode len = getLength();
-            if (len.stamp().getStackKind() != JavaKind.Long) {
-                len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph());
+            if (len.stamp(NodeView.DEFAULT).getStackKind() != JavaKind.Long) {
+                len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph(), NodeView.DEFAULT);
             }
             ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len));
             call.setStateAfter(stateAfter());
@@ -232,8 +233,8 @@
             // Can treat as disjoint
             disjoint = true;
         }
-        PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp().asConstant();
-        PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp().asConstant();
+        PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp(NodeView.DEFAULT).asConstant();
+        PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp(NodeView.DEFAULT).asConstant();
         if (constantSrc != null && constantDst != null) {
             if (!aligned) {
                 aligned = isHeapWordAligned(constantSrc, componentKind) && isHeapWordAligned(constantDst, componentKind);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Fri Dec 01 11:17:45 2017 -0800
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -90,11 +91,12 @@
 
     private enum ArrayCopyTypeCheck {
         UNDEFINED_ARRAY_TYPE_CHECK,
-        // we know that both objects are arrays and have the same type
+        // either we know that both objects are arrays and have the same type,
+        // or we apply generic array copy snippet, which enforces type check
         NO_ARRAY_TYPE_CHECK,
         // can be used when we know that one of the objects is a primitive array
         HUB_BASED_ARRAY_TYPE_CHECK,
-        // must be used when we don't have sufficient information to use one of the others
+        // can be used when we know that one of the objects is an object array
         LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
     }
 
@@ -232,18 +234,18 @@
 
     @Snippet(allowPartialIntrinsicArgumentMismatch = true)
     public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        if (probability(FREQUENT_PROBABILITY, length > 0)) {
-            counters.genericArraycopyDifferentTypeCounter.inc();
-            counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
-            int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
-            if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
-                /*
-                 * the stub doesn't throw the ArrayStoreException, but returns the number of copied
-                 * elements (xor'd with -1).
-                 */
-                copiedElements ^= -1;
-                System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
-            }
+        // The length > 0 check should not be placed here because generic array copy stub should
+        // enforce type check. This is fine performance-wise because this snippet is rarely used.
+        counters.genericArraycopyDifferentTypeCounter.inc();
+        counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
+        int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
+        if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+            /*
+             * the stub doesn't throw the ArrayStoreException, but returns the number of copied
+             * elements (xor'd with -1).
+             */
+            copiedElements ^= -1;
+            System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
         }
     }
 
@@ -275,21 +277,14 @@
         } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
             KlassPointer srcHub = loadHub(nonNullSrc);
             KlassPointer destHub = loadHub(nonNullDest);
-            checkArrayType(srcHub);
-            checkArrayType(destHub);
+            if (probability(SLOW_PATH_PROBABILITY, readLayoutHelper(srcHub) != readLayoutHelper(destHub))) {
+                DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+            }
         } else {
             ReplacementsUtil.staticAssert(false, "unknown array type check");
         }
     }
 
-    private static int checkArrayType(KlassPointer nonNullHub) {
-        int layoutHelper = readLayoutHelper(nonNullHub);
-        if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        return layoutHelper;
-    }
-
     static class Counters {
         final SnippetCounter checkSuccessCounter;
         final SnippetCounter checkAIOOBECounter;
@@ -381,8 +376,8 @@
             SnippetInfo snippetInfo;
             ArrayCopyTypeCheck arrayTypeCheck;
 
-            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
             if (!canBeArray(srcType) || !canBeArray(destType)) {
                 // at least one of the objects is definitely not an array - use the native call
                 // right away as the copying will fail anyways
@@ -399,7 +394,8 @@
                 } else if (srcComponentType == null && destComponentType == null) {
                     // we don't know anything about the types - use the generic copying
                     snippetInfo = arraycopyGenericSnippet;
-                    arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                    // no need for additional type check to avoid duplicated work
+                    arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
                 } else if (srcComponentType != null && destComponentType != null) {
                     if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
                         // it depends on the array content if the copy succeeds - we need
@@ -416,14 +412,14 @@
                 } else {
                     ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
                     if (nonNullComponentType.isPrimitive()) {
-                        // one involved object is a primitive array - we can safely assume that we
-                        // are copying primitive arrays
+                        // one involved object is a primitive array - it is sufficient to directly
+                        // compare the hub.
                         snippetInfo = arraycopyExactSnippet;
                         arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
                         elementKind = nonNullComponentType.getJavaKind();
                     } else {
-                        // one involved object is an object array - we can safely assume that we are
-                        // copying object arrays that might require a store check
+                        // one involved object is an object array - the other array's element type
+                        // may be primitive or object, hence we compare the layout helper.
                         snippetInfo = arraycopyCheckcastSnippet;
                         arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
                     }
@@ -432,7 +428,12 @@
 
             // a few special cases that are easier to handle when all other variables already have a
             // value
-            if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
+            if (snippetInfo != arraycopyNativeSnippet && snippetInfo != arraycopyGenericSnippet && arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
+                // Copying 0 element between object arrays with conflicting types will not throw an
+                // exception - once we pass the preliminary element type checks that we are not
+                // mixing arrays of different basic types, ArrayStoreException is only thrown when
+                // an *astore would have thrown it. Therefore, copying null between object arrays
+                // with conflicting types will also succeed (we do not optimize for such case here).
                 snippetInfo = arraycopyZeroLengthSnippet;
             } else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
                 snippetInfo = arraycopyUnrolledSnippet;
@@ -495,8 +496,8 @@
         }
 
         public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
-            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
 
             if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
                 return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
@@ -115,9 +116,10 @@
         graph().addBeforeFixed(this, basePtr);
 
         int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
-        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
         ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
-        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
+        ValueNode offset = graph().unique(
+                        new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp(NodeView.DEFAULT)), getArrayBaseOffset(JavaKind.Object), graph())));
         return graph().unique(new OffsetAddressNode(basePtr, offset));
     }
 
@@ -129,8 +131,8 @@
             ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
             ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
             ValueNode len = getLength();
-            if (len.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
-                len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+            if (len.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
+                len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
             }
             ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass));
             call.setStateAfter(stateAfter());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
@@ -106,8 +107,8 @@
     }
 
     private ValueNode wordValue(ValueNode value) {
-        if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
-            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        if (value.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
+            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
         }
         return value;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
 import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
@@ -120,7 +121,7 @@
             for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
                 int index = param.index();
                 if (method.getParameterAnnotation(NonNullParameter.class, index) != null) {
-                    param.setStamp(param.stamp().join(StampFactory.objectNonNull()));
+                    param.setStamp(param.stamp(NodeView.DEFAULT).join(StampFactory.objectNonNull()));
                 }
             }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/PointerCastNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/word/PointerCastNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -59,7 +60,7 @@
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         Value value = generator.operand(input);
-        assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp())) : "PointerCastNode shouldn't change the LIRKind";
+        assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT))) : "PointerCastNode shouldn't change the LIRKind";
 
         generator.setResult(this, value);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Dec 01 11:17:45 2017 -0800
@@ -330,6 +330,7 @@
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
@@ -1092,71 +1093,71 @@
     }
 
     protected ValueNode genIntegerAdd(ValueNode x, ValueNode y) {
-        return AddNode.create(x, y);
+        return AddNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerSub(ValueNode x, ValueNode y) {
-        return SubNode.create(x, y);
+        return SubNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerMul(ValueNode x, ValueNode y) {
-        return MulNode.create(x, y);
+        return MulNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatAdd(ValueNode x, ValueNode y) {
-        return AddNode.create(x, y);
+        return AddNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatSub(ValueNode x, ValueNode y) {
-        return SubNode.create(x, y);
+        return SubNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatMul(ValueNode x, ValueNode y) {
-        return MulNode.create(x, y);
+        return MulNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
-        return FloatDivNode.create(x, y);
+        return FloatDivNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
-        return new RemNode(x, y);
+        return RemNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerDiv(ValueNode x, ValueNode y) {
-        return new SignedDivNode(x, y);
+        return SignedDivNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genIntegerRem(ValueNode x, ValueNode y) {
-        return new SignedRemNode(x, y);
+        return SignedRemNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genNegateOp(ValueNode x) {
-        return NegateNode.create(x);
+        return NegateNode.create(x, NodeView.DEFAULT);
     }
 
     protected ValueNode genLeftShift(ValueNode x, ValueNode y) {
-        return LeftShiftNode.create(x, y);
+        return LeftShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genRightShift(ValueNode x, ValueNode y) {
-        return RightShiftNode.create(x, y);
+        return RightShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genUnsignedRightShift(ValueNode x, ValueNode y) {
-        return new UnsignedRightShiftNode(x, y);
+        return UnsignedRightShiftNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genAnd(ValueNode x, ValueNode y) {
-        return AndNode.create(x, y);
+        return AndNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genOr(ValueNode x, ValueNode y) {
-        return OrNode.create(x, y);
+        return OrNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genXor(ValueNode x, ValueNode y) {
-        return XorNode.create(x, y);
+        return XorNode.create(x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess) {
@@ -1164,19 +1165,19 @@
     }
 
     protected ValueNode genFloatConvert(FloatConvert op, ValueNode input) {
-        return FloatConvertNode.create(op, input);
+        return FloatConvertNode.create(op, input, NodeView.DEFAULT);
     }
 
     protected ValueNode genNarrow(ValueNode input, int bitCount) {
-        return NarrowNode.create(input, bitCount);
+        return NarrowNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected ValueNode genSignExtend(ValueNode input, int bitCount) {
-        return SignExtendNode.create(input, bitCount);
+        return SignExtendNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected ValueNode genZeroExtend(ValueNode input, int bitCount) {
-        return ZeroExtendNode.create(input, bitCount);
+        return ZeroExtendNode.create(input, bitCount, NodeView.DEFAULT);
     }
 
     protected void genGoto() {
@@ -1191,15 +1192,15 @@
     }
 
     protected LogicNode genObjectEquals(ValueNode x, ValueNode y) {
-        return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y);
+        return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, NodeView.DEFAULT);
     }
 
     protected LogicNode genIntegerEquals(ValueNode x, ValueNode y) {
-        return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y);
+        return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
     }
 
     protected LogicNode genIntegerLessThan(ValueNode x, ValueNode y) {
-        return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y);
+        return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
     }
 
     protected ValueNode genUnique(ValueNode x) {
@@ -1219,7 +1220,7 @@
 
         ValueNode exception = frameState.pop(JavaKind.Object);
         FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
-        ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
+        ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp(NodeView.DEFAULT).join(objectNonNull()), nullCheck));
         lastInstr.setNext(handleException(nonNullException, bci(), false));
     }
 
@@ -1244,7 +1245,7 @@
     }
 
     protected ValueNode genConditional(ValueNode x) {
-        return ConditionalNode.create((LogicNode) x);
+        return ConditionalNode.create((LogicNode) x, NodeView.DEFAULT);
     }
 
     protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) {
@@ -1275,7 +1276,7 @@
     }
 
     protected ValueNode emitExplicitNullCheck(ValueNode receiver) {
-        if (StampTool.isPointerNonNull(receiver.stamp())) {
+        if (StampTool.isPointerNonNull(receiver.stamp(NodeView.DEFAULT))) {
             return receiver;
         }
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
@@ -1293,7 +1294,7 @@
     protected void emitExplicitBoundsCheck(ValueNode index, ValueNode length) {
         AbstractBeginNode trueSucc = graph.add(new BeginNode());
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index));
-        append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length)), trueSucc, exception, FAST_PATH_PROBABILITY));
+        append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length, NodeView.DEFAULT)), trueSucc, exception, FAST_PATH_PROBABILITY));
         lastInstr = trueSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
@@ -1803,7 +1804,7 @@
             this.args = args;
             this.resultType = resultType;
             this.beforeStackSize = frameState.stackSize();
-            this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp());
+            this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp(NodeView.DEFAULT));
             this.nodeCount = graph.getNodeCount();
             this.mark = graph.getMark();
         }
@@ -1817,7 +1818,8 @@
                 int expectedStackSize = beforeStackSize + resultType.getSlotCount();
                 assert expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize());
                 NodeIterable<Node> newNodes = graph.getNewNodes(mark);
-                assert !needsNullCheck || isPointerNonNull(args[0].stamp()) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"), args[0]);
+                assert !needsNullCheck || isPointerNonNull(args[0].stamp(NodeView.DEFAULT)) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"),
+                                args[0]);
                 for (Node n : newNodes) {
                     if (n instanceof StateSplit) {
                         StateSplit stateSplit = (StateSplit) n;
@@ -1891,7 +1893,7 @@
             LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
             LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
             ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
-            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected));
+            LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
 
             JavaTypeProfile profile = null;
             if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@@ -2394,7 +2396,7 @@
         if (kind != returnKind) {
             // sub-word integer
             assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
-            IntegerStamp stamp = (IntegerStamp) value.stamp();
+            IntegerStamp stamp = (IntegerStamp) value.stamp(NodeView.DEFAULT);
 
             // the bytecode verifier doesn't check that the value is in the correct range
             if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
@@ -2480,7 +2482,7 @@
         JsrScope scope = currentBlock.getJsrScope();
         int retAddress = scope.nextReturnAddress();
         ConstantNode returnBciNode = getJsrConstant(retAddress);
-        LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode);
+        LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
         guard = graph.addOrUniqueWithInputs(guard);
         append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
         if (!successor.getJsrScope().equals(scope.pop())) {
@@ -3184,7 +3186,7 @@
     private void genConditionalForIf(BciBlock trueBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt, boolean genReturn) {
         ConstantNode trueValue = graph.unique(ConstantNode.forInt(trueBlockInt));
         ConstantNode falseValue = graph.unique(ConstantNode.forInt(falseBlockInt));
-        ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue);
+        ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue, NodeView.DEFAULT);
         if (conditionalNode.graph() == null) {
             conditionalNode = graph.addOrUniqueWithInputs(conditionalNode);
         }
@@ -3716,7 +3718,7 @@
             }
         }
 
-        boolean nonNull = ((ObjectStamp) object.stamp()).nonNull();
+        boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
         if (castNode == null) {
             LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
             if (condition.isTautology()) {
@@ -4174,7 +4176,8 @@
         ValueNode value = frameState.pop(JavaKind.Int);
 
         int nofCases = bs.numberOfCases();
-        double[] keyProbabilities = switchProbability(nofCases + 1, bci);
+        int nofCasesPlusDefault = nofCases + 1;
+        double[] keyProbabilities = switchProbability(nofCasesPlusDefault, bci);
 
         EconomicMap<Integer, SuccessorInfo> bciToBlockSuccessorIndex = EconomicMap.create(Equivalence.DEFAULT);
         for (int i = 0; i < currentBlock.getSuccessorCount(); i++) {
@@ -4184,11 +4187,11 @@
 
         ArrayList<BciBlock> actualSuccessors = new ArrayList<>();
         int[] keys = new int[nofCases];
-        int[] keySuccessors = new int[nofCases + 1];
+        int[] keySuccessors = new int[nofCasesPlusDefault];
         int deoptSuccessorIndex = -1;
         int nextSuccessorIndex = 0;
         boolean constantValue = value.isConstant();
-        for (int i = 0; i < nofCases + 1; i++) {
+        for (int i = 0; i < nofCasesPlusDefault; i++) {
             if (i < nofCases) {
                 keys[i] = bs.keyAt(i);
             }
@@ -4200,7 +4203,7 @@
                 }
                 keySuccessors[i] = deoptSuccessorIndex;
             } else {
-                int targetBci = i >= nofCases ? bs.defaultTarget() : bs.targetAt(i);
+                int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
                 SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
                 if (info.actualIndex < 0) {
                     info.actualIndex = nextSuccessorIndex++;
@@ -4209,6 +4212,48 @@
                 keySuccessors[i] = info.actualIndex;
             }
         }
+        /*
+         * When the profile indicates a case is never taken, the above code will cause the case to
+         * deopt should it be subsequently encountered. However, the case may share code with
+         * another case that is taken according to the profile.
+         *
+         * For example:
+         * // @formatter:off
+         * switch (opcode) {
+         *     case GOTO:
+         *     case GOTO_W: {
+         *         // emit goto code
+         *         break;
+         *     }
+         * }
+         * // @formatter:on
+         *
+         * The profile may indicate the GOTO_W case is never taken, and thus a deoptimization stub
+         * will be emitted. There might be optimization opportunity if additional branching based
+         * on opcode is within the case block. Specially, if there is only single case that
+         * reaches a target, we have better chance cutting out unused branches. Otherwise,
+         * it might be beneficial routing to the same code instead of deopting.
+         *
+         * The following code rewires deoptimization stub to existing resolved branch target if
+         * the target is connected by more than 1 cases.
+         */
+        if (deoptSuccessorIndex >= 0) {
+            int[] connectedCases = new int[nextSuccessorIndex];
+            for (int i = 0; i < nofCasesPlusDefault; i++) {
+                connectedCases[keySuccessors[i]]++;
+            }
+
+            for (int i = 0; i < nofCasesPlusDefault; i++) {
+                if (keySuccessors[i] == deoptSuccessorIndex) {
+                    int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
+                    SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
+                    int rewiredIndex = info.actualIndex;
+                    if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) {
+                        keySuccessors[i] = info.actualIndex;
+                    }
+                }
+            }
+        }
 
         genIntegerSwitch(value, actualSuccessors, keys, keyProbabilities, keySuccessors);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -55,6 +55,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -460,7 +461,7 @@
     }
 
     private ValuePhiNode createValuePhi(ValueNode currentValue, ValueNode otherValue, AbstractMergeNode block) {
-        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block));
+        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp(NodeView.DEFAULT).unrestricted(), block));
         for (int i = 0; i < block.phiPredecessorCount(); i++) {
             phi.addInput(currentValue);
         }
@@ -558,7 +559,7 @@
         }
         assert !block.isPhiAtMerge(value) : "phi function for this block already created";
 
-        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp() : value.stamp().unrestricted(), block));
+        ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp(NodeView.DEFAULT) : value.stamp(NodeView.DEFAULT).unrestricted(), block));
         phi.addInput(value);
         return phi;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/jdk/Unsafe_compareAndSwapNullCheck.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/jdk/Unsafe_compareAndSwapNullCheck.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,7 +23,6 @@
 package org.graalvm.compiler.jtt.jdk;
 
 import org.graalvm.compiler.jtt.JTTTest;
-import org.junit.Assume;
 import org.junit.Test;
 
 public class Unsafe_compareAndSwapNullCheck extends JTTTest {
@@ -48,8 +47,6 @@
 
     @Test
     public void run0() throws Throwable {
-        // GR-2921: Unsafe_compareAndSwapNullCheck test crashes on jdk9
-        Assume.assumeTrue(Java8OrEarlier);
         runTest(getInitialOptions(), EMPTY, false, true, "test", null, 1L, 2L);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Fri Dec 01 11:17:45 2017 -0800
@@ -299,16 +299,23 @@
 
         @Def({REG}) protected AllocatableValue result;
         @Use({COMPOSITE, UNINITIALIZED}) protected AMD64AddressValue address;
+        private final OperandSize size;
 
-        public LeaOp(AllocatableValue result, AMD64AddressValue address) {
+        public LeaOp(AllocatableValue result, AMD64AddressValue address, OperandSize size) {
             super(TYPE);
             this.result = result;
             this.address = address;
+            this.size = size;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
+            if (size == OperandSize.QWORD) {
+                masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
+            } else {
+                assert size == OperandSize.DWORD;
+                masm.lead(asRegister(result, AMD64Kind.DWORD), address.toAddress());
+            }
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRIntrospection.java	Fri Dec 01 11:17:45 2017 -0800
@@ -340,7 +340,7 @@
     private static boolean isPrintableAsciiString(byte[] array) {
         for (byte b : array) {
             char c = (char) b;
-            if (c != 0 && c < 0x20 && c > 0x7F) {
+            if (c != 0 && (c < 0x20 || c > 0x7F)) {
                 return false;
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -159,97 +159,101 @@
 
         intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops());
 
-        // iterate all blocks
-        for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
-            try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
+        try {
+            // iterate all blocks
+            for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
+                try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
 
-                final BitSet liveGen = new BitSet(liveSize);
-                final BitSet liveKill = new BitSet(liveSize);
+                    final BitSet liveGen = new BitSet(liveSize);
+                    final BitSet liveKill = new BitSet(liveSize);
 
-                ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
-                int numInst = instructions.size();
+                    ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
+                    int numInst = instructions.size();
 
-                ValueConsumer useConsumer = (operand, mode, flags) -> {
-                    if (isVariable(operand)) {
-                        int operandNum = allocator.operandNumber(operand);
-                        if (!liveKill.get(operandNum)) {
-                            liveGen.set(operandNum);
-                            if (debug.isLogEnabled()) {
-                                debug.log("liveGen for operand %d(%s)", operandNum, operand);
+                    ValueConsumer useConsumer = (operand, mode, flags) -> {
+                        if (isVariable(operand)) {
+                            int operandNum = allocator.operandNumber(operand);
+                            if (!liveKill.get(operandNum)) {
+                                liveGen.set(operandNum);
+                                if (debug.isLogEnabled()) {
+                                    debug.log("liveGen for operand %d(%s)", operandNum, operand);
+                                }
+                            }
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
                             }
                         }
-                        if (block.getLoop() != null) {
-                            intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
+
+                        if (allocator.detailedAsserts) {
+                            verifyInput(block, liveKill, operand);
                         }
+                    };
+                    ValueConsumer stateConsumer = (operand, mode, flags) -> {
+                        if (LinearScan.isVariableOrRegister(operand)) {
+                            int operandNum = allocator.operandNumber(operand);
+                            if (!liveKill.get(operandNum)) {
+                                liveGen.set(operandNum);
+                                if (debug.isLogEnabled()) {
+                                    debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
+                                }
+                            }
+                        }
+                    };
+                    ValueConsumer defConsumer = (operand, mode, flags) -> {
+                        if (isVariable(operand)) {
+                            int varNum = allocator.operandNumber(operand);
+                            liveKill.set(varNum);
+                            if (debug.isLogEnabled()) {
+                                debug.log("liveKill for operand %d(%s)", varNum, operand);
+                            }
+                            if (block.getLoop() != null) {
+                                intervalInLoop.setBit(varNum, block.getLoop().getIndex());
+                            }
+                        }
+
+                        if (allocator.detailedAsserts) {
+                            /*
+                             * Fixed intervals are never live at block boundaries, so they need not
+                             * be processed in live sets. Process them only in debug mode so that
+                             * this can be checked
+                             */
+                            verifyTemp(liveKill, operand);
+                        }
+                    };
+
+                    // iterate all instructions of the block
+                    for (int j = 0; j < numInst; j++) {
+                        final LIRInstruction op = instructions.get(j);
+
+                        try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
+                            op.visitEachInput(useConsumer);
+                            op.visitEachAlive(useConsumer);
+                            /*
+                             * Add uses of live locals from interpreter's point of view for proper
+                             * debug information generation.
+                             */
+                            op.visitEachState(stateConsumer);
+                            op.visitEachTemp(defConsumer);
+                            op.visitEachOutput(defConsumer);
+                        }
+                    } // end of instruction iteration
+
+                    BlockData blockSets = allocator.getBlockData(block);
+                    blockSets.liveGen = liveGen;
+                    blockSets.liveKill = liveKill;
+                    blockSets.liveIn = new BitSet(liveSize);
+                    blockSets.liveOut = new BitSet(liveSize);
+
+                    if (debug.isLogEnabled()) {
+                        debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
+                        debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
                     }
 
-                    if (allocator.detailedAsserts) {
-                        verifyInput(block, liveKill, operand);
-                    }
-                };
-                ValueConsumer stateConsumer = (operand, mode, flags) -> {
-                    if (LinearScan.isVariableOrRegister(operand)) {
-                        int operandNum = allocator.operandNumber(operand);
-                        if (!liveKill.get(operandNum)) {
-                            liveGen.set(operandNum);
-                            if (debug.isLogEnabled()) {
-                                debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
-                            }
-                        }
-                    }
-                };
-                ValueConsumer defConsumer = (operand, mode, flags) -> {
-                    if (isVariable(operand)) {
-                        int varNum = allocator.operandNumber(operand);
-                        liveKill.set(varNum);
-                        if (debug.isLogEnabled()) {
-                            debug.log("liveKill for operand %d(%s)", varNum, operand);
-                        }
-                        if (block.getLoop() != null) {
-                            intervalInLoop.setBit(varNum, block.getLoop().getIndex());
-                        }
-                    }
-
-                    if (allocator.detailedAsserts) {
-                        /*
-                         * Fixed intervals are never live at block boundaries, so they need not be
-                         * processed in live sets. Process them only in debug mode so that this can
-                         * be checked
-                         */
-                        verifyTemp(liveKill, operand);
-                    }
-                };
-
-                // iterate all instructions of the block
-                for (int j = 0; j < numInst; j++) {
-                    final LIRInstruction op = instructions.get(j);
-
-                    try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
-                        op.visitEachInput(useConsumer);
-                        op.visitEachAlive(useConsumer);
-                        /*
-                         * Add uses of live locals from interpreter's point of view for proper debug
-                         * information generation.
-                         */
-                        op.visitEachState(stateConsumer);
-                        op.visitEachTemp(defConsumer);
-                        op.visitEachOutput(defConsumer);
-                    }
-                } // end of instruction iteration
-
-                BlockData blockSets = allocator.getBlockData(block);
-                blockSets.liveGen = liveGen;
-                blockSets.liveKill = liveKill;
-                blockSets.liveIn = new BitSet(liveSize);
-                blockSets.liveOut = new BitSet(liveSize);
-
-                if (debug.isLogEnabled()) {
-                    debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
-                    debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
                 }
-
-            }
-        } // end of block iteration
+            } // end of block iteration
+        } catch (OutOfMemoryError oom) {
+            throw new PermanentBailoutException(oom, "Out-of-memory during live set allocation of size %d", liveSize);
+        }
     }
 
     private void verifyTemp(BitSet liveKill, Value operand) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantTree.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/constopt/ConstantTree.java	Fri Dec 01 11:17:45 2017 -0800
@@ -76,7 +76,7 @@
 
         public List<UseEntry> getUsages() {
             if (usages == null) {
-                Collections.emptyList();
+                return Collections.emptyList();
             }
             return usages;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/BasicInductionVariable.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/BasicInductionVariable.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -70,7 +71,7 @@
 
     @Override
     public Direction direction() {
-        Stamp stamp = rawStride.stamp();
+        Stamp stamp = rawStride.stamp(NodeView.DEFAULT);
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
             Direction dir = null;
@@ -140,27 +141,27 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        Stamp fromStamp = phi.stamp();
+        Stamp fromStamp = phi.stamp(NodeView.DEFAULT);
         StructuredGraph graph = graph();
         ValueNode stride = strideNode();
         ValueNode initNode = this.initNode();
         if (!fromStamp.isCompatible(stamp)) {
-            stride = IntegerConvertNode.convert(stride, stamp, graph());
-            initNode = IntegerConvertNode.convert(initNode, stamp, graph());
+            stride = IntegerConvertNode.convert(stride, stamp, graph(), NodeView.DEFAULT);
+            initNode = IntegerConvertNode.convert(initNode, stamp, graph(), NodeView.DEFAULT);
         }
         ValueNode maxTripCount = loop.counted().maxTripCountNode(assumePositiveTripCount);
-        if (!maxTripCount.stamp().isCompatible(stamp)) {
-            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
+        if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
         }
         return add(graph, mul(graph, stride, sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
     }
 
     @Override
     public ValueNode exitValueNode() {
-        Stamp stamp = phi.stamp();
+        Stamp stamp = phi.stamp(NodeView.DEFAULT);
         ValueNode maxTripCount = loop.counted().maxTripCountNode(false);
-        if (!maxTripCount.stamp().isCompatible(stamp)) {
-            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
+        if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
+            maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
         }
         return add(graph(), mul(graph(), strideNode(), maxTripCount), initNode());
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.GuardNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -69,7 +70,7 @@
 
     public ValueNode maxTripCountNode(boolean assumePositive) {
         StructuredGraph graph = iv.valueNode().graph();
-        Stamp stamp = iv.valueNode().stamp();
+        Stamp stamp = iv.valueNode().stamp(NodeView.DEFAULT);
         ValueNode range = sub(graph, end, iv.initNode());
 
         ValueNode oneDirection;
@@ -84,7 +85,7 @@
         }
         // round-away-from-zero divison: (range + stride -/+ 1) / stride
         ValueNode denominator = range;
-        if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
+        if (!oneDirection.stamp(NodeView.DEFAULT).equals(iv.strideNode().stamp(NodeView.DEFAULT))) {
             ValueNode subedRanged = sub(graph, range, oneDirection);
             denominator = add(graph, subedRanged, iv.strideNode());
         }
@@ -204,7 +205,7 @@
         if (overflowGuard != null) {
             return overflowGuard;
         }
-        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp();
+        IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
         StructuredGraph graph = iv.valueNode().graph();
         CompareNode cond; // we use a negated guard with a < condition to achieve a >=
         ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
@@ -230,6 +231,6 @@
     }
 
     public IntegerStamp getStamp() {
-        return (IntegerStamp) iv.valueNode().stamp();
+        return (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedConvertedInductionVariable.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedConvertedInductionVariable.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.loop;
 
 import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 
@@ -49,12 +50,12 @@
 
     @Override
     public ValueNode initNode() {
-        return IntegerConvertNode.convert(base.initNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.initNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
     public ValueNode strideNode() {
-        return IntegerConvertNode.convert(base.strideNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.strideNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
@@ -84,7 +85,7 @@
 
     @Override
     public ValueNode exitValueNode() {
-        return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph());
+        return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph(), NodeView.DEFAULT);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedOffsetInductionVariable.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedOffsetInductionVariable.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
@@ -90,14 +91,14 @@
     @Override
     public ValueNode strideNode() {
         if (value instanceof SubNode && base.valueNode() == value.getY()) {
-            return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode()));
+            return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode(), NodeView.DEFAULT));
         }
         return base.strideNode();
     }
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph()));
+        return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph(), NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedScaledInductionVariable.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DerivedScaledInductionVariable.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 import org.graalvm.compiler.nodes.calc.NegateNode;
@@ -45,7 +46,7 @@
 
     public DerivedScaledInductionVariable(LoopEx loop, InductionVariable base, NegateNode value) {
         super(loop, base);
-        this.scale = ConstantNode.forIntegerStamp(value.stamp(), -1, value.graph());
+        this.scale = ConstantNode.forIntegerStamp(value.stamp(NodeView.DEFAULT), -1, value.graph());
         this.value = value;
     }
 
@@ -60,7 +61,7 @@
 
     @Override
     public Direction direction() {
-        Stamp stamp = scale.stamp();
+        Stamp stamp = scale.stamp(NodeView.DEFAULT);
         if (stamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) stamp;
             if (integerStamp.isStrictlyPositive()) {
@@ -104,7 +105,7 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
+        return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph(), NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/InductionVariable.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/InductionVariable.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 
@@ -93,7 +94,7 @@
      * {@link CountedLoopInfo#isExactTripCount()} returns false for the containing loop.
      */
     public ValueNode extremumNode() {
-        return extremumNode(false, valueNode().stamp());
+        return extremumNode(false, valueNode().stamp(NodeView.DEFAULT));
     }
 
     public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -188,7 +189,7 @@
             if (!binary.isAssociative()) {
                 continue;
             }
-            ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY());
+            ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY(), NodeView.DEFAULT);
             if (result != binary) {
                 if (!result.isAlive()) {
                     assert !result.isDeleted();
@@ -259,8 +260,8 @@
                     if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1) {
                         return false;
                     }
-                    IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp();
-                    IntegerStamp limitStamp = (IntegerStamp) limit.stamp();
+                    IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(NodeView.DEFAULT);
+                    IntegerStamp limitStamp = (IntegerStamp) limit.stamp(NodeView.DEFAULT);
                     if (iv.direction() == Direction.Up) {
                         if (initStamp.upperBound() > limitStamp.lowerBound()) {
                             return false;
@@ -392,12 +393,12 @@
                 } else {
                     boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
                     if (!isValidConvert && op instanceof ZeroExtendNode) {
-                        IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp();
+                        IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp(NodeView.DEFAULT);
                         isValidConvert = inputStamp.isPositive();
                     }
 
                     if (isValidConvert) {
-                        iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(), op);
+                        iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
                     }
                 }
 
@@ -411,7 +412,7 @@
     }
 
     private static ValueNode addSub(LoopEx loop, ValueNode op, ValueNode base) {
-        if (op.stamp() instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
+        if (op.stamp(NodeView.DEFAULT) instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
             BinaryArithmeticNode<?> aritOp = (BinaryArithmeticNode<?>) op;
             if (aritOp.getX() == base && loop.isOutsideLoop(aritOp.getY())) {
                 return aritOp.getY();
@@ -434,7 +435,7 @@
         if (op instanceof LeftShiftNode) {
             LeftShiftNode shift = (LeftShiftNode) op;
             if (shift.getX() == base && shift.getY().isConstant()) {
-                return ConstantNode.forIntegerStamp(base.stamp(), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
+                return ConstantNode.forIntegerStamp(base.stamp(NodeView.DEFAULT), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
             }
         }
         return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragment.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -460,7 +461,7 @@
                 if (newVpn != null) {
                     PhiNode phi;
                     if (vpn instanceof ValueProxyNode) {
-                        phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge));
+                        phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(NodeView.DEFAULT), merge));
                     } else if (vpn instanceof GuardProxyNode) {
                         phi = graph.addWithoutUnique(new GuardPhiNode(merge));
                     } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Fri Dec 01 11:17:45 2017 -0800
@@ -48,6 +48,7 @@
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.SafepointNode;
@@ -213,11 +214,11 @@
             }
             long originalStride = unrollFactor == 1 ? iv.constantStride() : iv.constantStride() / unrollFactor;
             if (iv.direction() == InductionVariable.Direction.Up) {
-                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * originalStride));
+                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * originalStride));
                 ValueNode newLimit = graph.addWithoutUnique(new SubNode(compareBound, aboveVal));
                 compareNode.replaceFirstInput(compareBound, newLimit);
             } else if (iv.direction() == InductionVariable.Direction.Down) {
-                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * -originalStride));
+                ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * -originalStride));
                 ValueNode newLimit = graph.addWithoutUnique(new AddNode(compareBound, aboveVal));
                 compareNode.replaceFirstInput(compareBound, newLimit);
             }
@@ -391,7 +392,7 @@
     private static PhiNode patchPhi(StructuredGraph graph, PhiNode phi, AbstractMergeNode merge) {
         PhiNode ret;
         if (phi instanceof ValuePhiNode) {
-            ret = new ValuePhiNode(phi.stamp(), merge);
+            ret = new ValuePhiNode(phi.stamp(NodeView.DEFAULT), merge);
         } else if (phi instanceof GuardPhiNode) {
             ret = new GuardPhiNode(merge);
         } else if (phi instanceof MemoryPhiNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/MathUtil.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,9 +24,11 @@
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.nodes.FixedNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
+import org.graalvm.compiler.nodes.calc.FixedBinaryNode;
 import org.graalvm.compiler.nodes.calc.SignedDivNode;
 
 /**
@@ -34,11 +36,11 @@
  */
 public class MathUtil {
     private static boolean isConstantOne(ValueNode v1) {
-        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
+        return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
     }
 
     private static boolean isConstantZero(ValueNode v1) {
-        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
+        return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
     }
 
     public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@@ -48,7 +50,7 @@
         if (isConstantZero(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.add(graph, v1, v2);
+        return BinaryArithmeticNode.add(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@@ -58,22 +60,24 @@
         if (isConstantOne(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.mul(graph, v1, v2);
+        return BinaryArithmeticNode.mul(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
         if (isConstantZero(v2)) {
             return v1;
         }
-        return BinaryArithmeticNode.sub(graph, v1, v2);
+        return BinaryArithmeticNode.sub(graph, v1, v2, NodeView.DEFAULT);
     }
 
     public static ValueNode divBefore(StructuredGraph graph, FixedNode before, ValueNode dividend, ValueNode divisor) {
         if (isConstantOne(divisor)) {
             return dividend;
         }
-        SignedDivNode div = graph.add(new SignedDivNode(dividend, divisor));
-        graph.addBeforeFixed(before, div);
+        ValueNode div = graph.addOrUniqueWithInputs(SignedDivNode.create(dividend, divisor, NodeView.DEFAULT));
+        if (div instanceof FixedBinaryNode) {
+            graph.addBeforeFixed(before, (FixedBinaryNode) div);
+        }
         return div;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo.processor/src/org/graalvm/compiler/nodeinfo/processor/GraphNodeProcessor.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo.processor/src/org/graalvm/compiler/nodeinfo/processor/GraphNodeProcessor.java	Fri Dec 01 11:17:45 2017 -0800
@@ -103,7 +103,6 @@
     private void reportException(Kind kind, Element element, Throwable t) {
         StringWriter buf = new StringWriter();
         t.printStackTrace(new PrintWriter(buf));
-        buf.toString();
         message(kind, element, "Exception thrown during processing: %s", buf.toString());
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.test.GraphTest;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionValues;
@@ -67,52 +68,52 @@
 
     @Test
     public void testBooleanConstant() {
-        assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testByteConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testShortConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testCharConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testIntConstant() {
-        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
-        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
-        assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
-        assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
+        assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
     public void testLongConstant() {
-        assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
-        assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
-        assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
-        assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
-        assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
+        assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
+        assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/NegateNodeCanonicalizationTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/NegateNodeCanonicalizationTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.options.OptionValues;
@@ -57,7 +58,7 @@
         for (byte i : a) {
             ConstantNode node = ConstantNode.forByte(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -67,7 +68,7 @@
         for (char i : a) {
             ConstantNode node = ConstantNode.forChar(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -77,7 +78,7 @@
         for (short i : a) {
             ConstantNode node = ConstantNode.forShort(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -87,7 +88,7 @@
         for (int i : a) {
             ConstantNode node = ConstantNode.forInt(i, graph);
             JavaConstant expected = JavaConstant.forInt(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -97,7 +98,7 @@
         for (long i : a) {
             ConstantNode node = ConstantNode.forLong(i, graph);
             JavaConstant expected = JavaConstant.forLong(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -107,7 +108,7 @@
         for (float i : a) {
             ConstantNode node = ConstantNode.forFloat(i, graph);
             JavaConstant expected = JavaConstant.forFloat(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
@@ -117,7 +118,7 @@
         for (double i : a) {
             ConstantNode node = ConstantNode.forDouble(i, graph);
             JavaConstant expected = JavaConstant.forDouble(-i);
-            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
+            assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampDoubleToLongTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampDoubleToLongTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,9 +79,9 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Long, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Long, param, NodeView.DEFAULT);
 
-        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Long.SIZE, resultStamp.getBits());
 
         for (long result : interestingLongs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampFloatToIntTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampFloatToIntTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,10 +79,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Int, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Int, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Integer.SIZE, resultStamp.getBits());
 
         for (int result : interestingInts) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampIntToFloatTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampIntToFloatTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,10 +70,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Float, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Float, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
+        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Float.SIZE, resultStamp.getBits());
 
         for (int input : interestingInts) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampLongToDoubleTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ReinterpretStampLongToDoubleTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -26,6 +26,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,10 +70,10 @@
     @Test
     public void run() {
         ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
-        ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Double, param);
+        ValueNode reinterpret = ReinterpretNode.create(JavaKind.Double, param, NodeView.DEFAULT);
         reinterpret.inferStamp();
 
-        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
+        FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
         Assert.assertEquals(Double.SIZE, resultStamp.getBits());
 
         for (long input : interestingLongs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -68,7 +68,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return mkStamp(newStamp);
     }
 
@@ -124,7 +124,8 @@
             }
 
             ConstantNode constant = (ConstantNode) forValue;
-            return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(),
+                            tool.getMetaAccess());
         } else if (forValue instanceof CompressionNode) {
             CompressionNode other = (CompressionNode) forValue;
             if (op != other.op && encoding.equals(other.encoding)) {
@@ -137,8 +138,8 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         boolean nonNull;
-        if (value.stamp() instanceof AbstractObjectStamp) {
-            nonNull = StampTool.isPointerNonNull(value.stamp());
+        if (value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp) {
+            nonNull = StampTool.isPointerNonNull(value.stamp(NodeView.DEFAULT));
         } else {
             // metaspace pointers are never null
             nonNull = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -134,7 +134,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         if (onlyUsedInVirtualState()) {
             gen.setResult(this, new ConstantValue(kind, value));
         } else {
@@ -525,7 +525,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
+            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp(NodeView.DEFAULT).unrestricted().toString() + ")";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryProxyNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/EntryProxyNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,7 +44,7 @@
     @Input ValueNode value;
 
     public EntryProxyNode(ValueNode value, EntryMarkerNode proxyPoint) {
-        super(TYPE, value.stamp().unrestricted());
+        super(TYPE, value.stamp(NodeView.DEFAULT).unrestricted());
         this.value = value;
         this.proxyPoint = proxyPoint;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -310,7 +310,7 @@
         @Input(InputType.Unchecked) Node proxyPoint;
 
         public ProxyPlaceholder(ValueNode value, MergeNode proxyPoint) {
-            super(TYPE, value.stamp());
+            super(TYPE, value.stamp(NodeView.DEFAULT));
             this.value = value;
             this.proxyPoint = proxyPoint;
         }
@@ -868,7 +868,7 @@
                 /* Now we have two different values, so we need to create a phi node. */
                 PhiNode phi;
                 if (proxy instanceof ValueProxyNode) {
-                    phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(), merge));
+                    phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(NodeView.DEFAULT), merge));
                 } else if (proxy instanceof GuardProxyNode) {
                     phi = graph.addWithoutUnique(new GuardPhiNode(merge));
                 } else {
@@ -1630,7 +1630,7 @@
         List<PhiNode> loopBeginPhis = new ArrayList<>(mergePhis.size());
         for (int i = 0; i < mergePhis.size(); i++) {
             PhiNode mergePhi = mergePhis.get(i);
-            PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(), loopBegin));
+            PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(NodeView.DEFAULT), loopBegin));
             mergePhi.replaceAtUsages(loopBeginPhi);
             /*
              * The first input of the new phi function is the original phi function, for the one
@@ -1793,7 +1793,7 @@
             assert irreducibleLoopHandler.header.phis().isEmpty();
 
             /* The new phi function for the loop variable. */
-            loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp().unrestricted(), irreducibleLoopHandler.header));
+            loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp(NodeView.DEFAULT).unrestricted(), irreducibleLoopHandler.header));
             for (int i = 0; i < irreducibleLoopHandler.header.phiPredecessorCount(); i++) {
                 loopVariablePhi.addInput(explosionHeadValue);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardedValueNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GuardedValueNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -53,7 +53,7 @@
     @Input ValueNode object;
 
     public GuardedValueNode(ValueNode object, GuardingNode guard) {
-        super(TYPE, object.stamp(), guard);
+        super(TYPE, object.stamp(NodeView.DEFAULT), guard);
         this.object = object;
     }
 
@@ -70,7 +70,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(object().stamp());
+        return updateStamp(object().stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -84,10 +84,10 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (getGuard() == null) {
-            if (stamp().equals(object().stamp())) {
+            if (stamp(NodeView.DEFAULT).equals(object().stamp(NodeView.DEFAULT))) {
                 return object();
             } else {
-                return PiNode.create(object(), stamp());
+                return PiNode.create(object(), stamp(NodeView.DEFAULT));
             }
         }
         return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -65,7 +65,6 @@
 import org.graalvm.util.Equivalence;
 
 import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.PrimitiveConstant;
@@ -238,7 +237,7 @@
             if (this.trueSuccessorProbability < probabilityB) {
                 // Reordering of those two if statements is beneficial from the point of view of
                 // their probabilities.
-                if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition())) {
+                if (prepareForSwap(tool, condition(), nextIf.condition())) {
                     // Reordering is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                     assert intermediateBegin.next() == nextIf;
                     AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
@@ -267,19 +266,19 @@
         }
     }
 
-    private boolean isUnboxedFrom(MetaAccessProvider meta, ValueNode x, ValueNode src) {
+    private boolean isUnboxedFrom(MetaAccessProvider meta, NodeView view, ValueNode x, ValueNode src) {
         if (x == src) {
             return true;
         } else if (x instanceof UnboxNode) {
-            return isUnboxedFrom(meta, ((UnboxNode) x).getValue(), src);
+            return isUnboxedFrom(meta, view, ((UnboxNode) x).getValue(), src);
         } else if (x instanceof PiNode) {
             PiNode pi = (PiNode) x;
-            return isUnboxedFrom(meta, pi.getOriginalNode(), src);
+            return isUnboxedFrom(meta, view, pi.getOriginalNode(), src);
         } else if (x instanceof LoadFieldNode) {
             LoadFieldNode load = (LoadFieldNode) x;
             ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
-            if (load.getValue().stamp().javaType(meta).equals(integerType)) {
-                return isUnboxedFrom(meta, load.getValue(), src);
+            if (load.getValue().stamp(view).javaType(meta).equals(integerType)) {
+                return isUnboxedFrom(meta, view, load.getValue(), src);
             } else {
                 return false;
             }
@@ -321,7 +320,8 @@
         ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
 
         // At least one argument for reference equal must be a boxed primitive.
-        if (!x.stamp().javaType(meta).equals(integerType) && !y.stamp().javaType(meta).equals(integerType)) {
+        NodeView view = NodeView.from(tool);
+        if (!x.stamp(view).javaType(meta).equals(integerType) && !y.stamp(view).javaType(meta).equals(integerType)) {
             return false;
         }
 
@@ -366,7 +366,8 @@
                 continue;
             }
             IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
-            if ((isUnboxedFrom(meta, equals.getX(), x) && isUnboxedFrom(meta, equals.getY(), y)) || (isUnboxedFrom(meta, equals.getX(), y) && isUnboxedFrom(meta, equals.getY(), x))) {
+            if ((isUnboxedFrom(meta, view, equals.getX(), x) && isUnboxedFrom(meta, view, equals.getY(), y)) ||
+                            (isUnboxedFrom(meta, view, equals.getX(), y) && isUnboxedFrom(meta, view, equals.getY(), x))) {
                 unboxCheck = fixed;
             }
         }
@@ -406,7 +407,8 @@
             ValueNode falseValue = phi.valueAt(falseEnd);
             ValueNode trueValue = phi.valueAt(trueEnd);
 
-            ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp());
+            NodeView view = NodeView.from(tool);
+            ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp(view), view);
             if (result != null) {
                 /*
                  * canonicalizeConditional returns possibly new nodes so add them to the graph.
@@ -477,8 +479,9 @@
     private boolean checkForUnsignedCompare(SimplifierTool tool) {
         assert trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages();
         if (condition() instanceof IntegerLessThanNode) {
+            NodeView view = NodeView.from(tool);
             IntegerLessThanNode lessThan = (IntegerLessThanNode) condition();
-            Constant y = lessThan.getY().stamp().asConstant();
+            Constant y = lessThan.getY().stamp(view).asConstant();
             if (y instanceof PrimitiveConstant && ((PrimitiveConstant) y).asLong() == 0 && falseSuccessor().next() instanceof IfNode) {
                 IfNode ifNode2 = (IfNode) falseSuccessor().next();
                 if (ifNode2.condition() instanceof IntegerLessThanNode) {
@@ -490,7 +493,8 @@
                      * Convert x >= 0 && x < positive which is represented as !(x < 0) && x <
                      * <positive> into an unsigned compare.
                      */
-                    if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp() instanceof IntegerStamp && ((IntegerStamp) lessThan2.getY().stamp()).isPositive() &&
+                    if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp(view) instanceof IntegerStamp &&
+                                    ((IntegerStamp) lessThan2.getY().stamp(view)).isPositive() &&
                                     sameDestination(trueSuccessor(), ifNode2.falseSuccessor)) {
                         below = graph().unique(new IntegerBelowNode(lessThan2.getX(), lessThan2.getY()));
                         // swap direction
@@ -506,7 +510,7 @@
                          */
                         JavaConstant positive = lessThan2.getX().asJavaConstant();
                         if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getJavaKind().getMaxValue()) {
-                            ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(), positive.asLong() + 1, graph());
+                            ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(view), positive.asLong() + 1, graph());
                             below = graph().unique(new IntegerBelowNode(lessThan.getX(), newLimit));
                         }
                     }
@@ -574,7 +578,7 @@
         return false;
     }
 
-    private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b) {
+    private static boolean prepareForSwap(SimplifierTool tool, LogicNode a, LogicNode b) {
         DebugContext debug = a.getDebug();
         if (a instanceof InstanceOfNode) {
             InstanceOfNode instanceOfA = (InstanceOfNode) a;
@@ -625,13 +629,13 @@
                     }
                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
                     boolean canSwap = false;
-                    if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) {
+                    if ((compareA.getX() == compareB.getX() && valuesDistinct(tool, compareA.getY(), compareB.getY()))) {
                         canSwap = true;
-                    } else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) {
+                    } else if ((compareA.getX() == compareB.getY() && valuesDistinct(tool, compareA.getY(), compareB.getX()))) {
                         canSwap = true;
-                    } else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) {
+                    } else if ((compareA.getY() == compareB.getX() && valuesDistinct(tool, compareA.getX(), compareB.getY()))) {
                         canSwap = true;
-                    } else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) {
+                    } else if ((compareA.getY() == compareB.getY() && valuesDistinct(tool, compareA.getX(), compareB.getX()))) {
                         canSwap = true;
                     }
 
@@ -646,16 +650,17 @@
         return false;
     }
 
-    private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
+    private static boolean valuesDistinct(SimplifierTool tool, ValueNode a, ValueNode b) {
         if (a.isConstant() && b.isConstant()) {
-            Boolean equal = constantReflection.constantEquals(a.asConstant(), b.asConstant());
+            Boolean equal = tool.getConstantReflection().constantEquals(a.asConstant(), b.asConstant());
             if (equal != null) {
                 return !equal.booleanValue();
             }
         }
 
-        Stamp stampA = a.stamp();
-        Stamp stampB = b.stamp();
+        NodeView view = NodeView.from(tool);
+        Stamp stampA = a.stamp(view);
+        Stamp stampB = b.stamp(view);
         return stampA.alwaysDistinct(stampB);
     }
 
@@ -691,7 +696,7 @@
                 } else if (distinct == 1) {
                     ValueNode trueValue = singlePhi.valueAt(trueEnd);
                     ValueNode falseValue = singlePhi.valueAt(falseEnd);
-                    ValueNode conditional = canonicalizeConditionalCascade(trueValue, falseValue);
+                    ValueNode conditional = canonicalizeConditionalCascade(tool, trueValue, falseValue);
                     if (conditional != null) {
                         singlePhi.setValueAt(trueEnd, conditional);
                         removeThroughFalseBranch(tool, merge);
@@ -710,7 +715,7 @@
                 if (trueValue == falseValue) {
                     value = trueValue;
                 } else {
-                    value = canonicalizeConditionalCascade(trueValue, falseValue);
+                    value = canonicalizeConditionalCascade(tool, trueValue, falseValue);
                     if (value == null) {
                         return false;
                     }
@@ -745,7 +750,7 @@
         }
     }
 
-    private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) {
+    private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode trueValue, ValueNode falseValue) {
         if (trueValue.getStackKind() != falseValue.getStackKind()) {
             return null;
         }
@@ -796,8 +801,9 @@
                 }
                 if (lessThan != null) {
                     assert equals != null;
+                    NodeView view = NodeView.from(tool);
                     if ((lessThan.getX() == equals.getX() && lessThan.getY() == equals.getY()) || (lessThan.getX() == equals.getY() && lessThan.getY() == equals.getX())) {
-                        return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp().getStackKind(), false));
+                        return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp(view).getStackKind(), false));
                     }
                 }
             }
@@ -1287,10 +1293,11 @@
                 GraphUtil.killCFG(end);
             } else {
                 // Need a new phi in case the frame state is used by more than the merge being
-                // removed
+                // removed.
+                NodeView view = NodeView.from(tool);
                 AbstractMergeNode newMerge = graph().add(new MergeNode());
                 PhiNode oldPhi = (PhiNode) oldMerge.usages().first();
-                PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(), newMerge));
+                PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(view), newMerge));
 
                 for (EndNode end : ends) {
                     newPhi.addInput(phiValues.get(end));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/LoopBeginNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -342,7 +342,7 @@
         for (int i = 0; i < phi.valueCount(); i++) {
             ValueNode input = phi.valueAt(i);
             long increment = NO_INCREMENT;
-            if (input != null && input instanceof AddNode && input.stamp() instanceof IntegerStamp) {
+            if (input != null && input instanceof AddNode && input.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 AddNode add = (AddNode) input;
                 if (add.getX() == phi && add.getY().isConstant()) {
                     increment = add.getY().asJavaConstant().asLong();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/NodeView.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, 2017, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.nodes;
+
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+
+/**
+ * Interface that overrides properties of a node, such as the node's stamp.
+ *
+ * This interface allows richer canonicalizations when the current compilation context can provide a
+ * narrower stamp than the one stored in the node itself. One such example is performing
+ * canonicalization late in the compilation, when the nodes are already scheduled, and benefit from
+ * additional stamp information from conditional checks in branches.
+ *
+ * For example, in the following code, <code>offset + i</code> can be canonicalized once it is
+ * scheduled into the branch:
+ *
+ * <pre>
+ * public void update(int offset, int i) {
+ *     if (i == 0) {
+ *         array[offset + i];
+ *     }
+ * }
+ * </pre>
+ */
+public interface NodeView {
+
+    NodeView DEFAULT = new Default();
+
+    class Default implements NodeView {
+        @Override
+        public Stamp stamp(ValueNode node) {
+            return node.stamp;
+        }
+    }
+
+    /**
+     * Return a view-specific stamp of the node.
+     *
+     * This stamp must be more specific than the default stamp.
+     */
+    Stamp stamp(ValueNode node);
+
+    static NodeView from(CanonicalizerTool tool) {
+        if (tool instanceof NodeView) {
+            return (NodeView) tool;
+        }
+        return DEFAULT;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -152,7 +152,7 @@
 
     public void addInput(ValueNode x) {
         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
-        assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
+        assert !(this instanceof ValuePhiNode) || x.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT));
         values().add(x);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -76,7 +76,7 @@
         super(c, stamp, guard);
         this.object = object;
         this.piStamp = stamp;
-        assert piStamp.isCompatible(object.stamp()) : "Object stamp not compatible to piStamp";
+        assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "Object stamp not compatible to piStamp";
         inferStamp();
     }
 
@@ -89,11 +89,12 @@
     }
 
     public PiNode(ValueNode object, ValueNode guard) {
-        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
+        this(object, AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)), guard);
     }
 
     public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
-        this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp())));
+        this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
+                        nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))));
     }
 
     public static ValueNode create(ValueNode object, Stamp stamp) {
@@ -113,7 +114,7 @@
     }
 
     public static ValueNode create(ValueNode object, ValueNode guard) {
-        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
+        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
@@ -123,7 +124,7 @@
 
     @SuppressWarnings("unused")
     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
-        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
+        Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value == null) {
             value = new PiNode(object, stamp, guard);
@@ -134,7 +135,8 @@
 
     @SuppressWarnings("unused")
     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
-        Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp()));
+        Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
+                        nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)));
         ValueNode value = canonical(object, stamp, null);
         if (value == null) {
             value = new PiNode(object, stamp);
@@ -165,7 +167,7 @@
     }
 
     private Stamp computeStamp() {
-        return piStamp.improveWith(object().stamp());
+        return piStamp.improveWith(object().stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -181,10 +183,10 @@
 
     public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard) {
         // Use most up to date stamp.
-        Stamp computedStamp = stamp.improveWith(object.stamp());
+        Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT));
 
         // The pi node does not give any additional information => skip it.
-        if (computedStamp.equals(object.stamp())) {
+        if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) {
             return object;
         }
 
@@ -192,14 +194,14 @@
             // Try to merge the pi node with a load node.
             if (object instanceof ReadNode) {
                 ReadNode readNode = (ReadNode) object;
-                readNode.setStamp(readNode.stamp().improveWith(stamp));
+                readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp));
                 return readNode;
             }
         } else {
             for (Node n : guard.asNode().usages()) {
                 if (n instanceof PiNode) {
                     PiNode otherPi = (PiNode) n;
-                    if (object == otherPi.object() && computedStamp.equals(otherPi.stamp())) {
+                    if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) {
                         /*
                          * Two PiNodes with the same guard and same result, so return the one with
                          * the more precise piStamp.
@@ -217,7 +219,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        Node value = canonical(object(), stamp(), getGuard());
+        Node value = canonical(object(), stamp(NodeView.DEFAULT), getGuard());
         if (value != null) {
             return value;
         }
@@ -232,7 +234,7 @@
     public void setOriginalNode(ValueNode newNode) {
         this.updateUsages(object, newNode);
         this.object = newNode;
-        assert piStamp.isCompatible(object.stamp()) : "New object stamp not compatible to piStamp";
+        assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "New object stamp not compatible to piStamp";
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Fri Dec 01 11:17:45 2017 -0800
@@ -360,9 +360,9 @@
             ValueNode result = returnNode.result();
             if (result != null) {
                 if (returnStamp == null) {
-                    returnStamp = result.stamp();
+                    returnStamp = result.stamp(NodeView.DEFAULT);
                 } else {
-                    returnStamp = returnStamp.meet(result.stamp());
+                    returnStamp = returnStamp.meet(result.stamp(NodeView.DEFAULT));
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -56,8 +56,8 @@
         this.stamp = stamp;
     }
 
-    public final Stamp stamp() {
-        return stamp;
+    public final Stamp stamp(NodeView view) {
+        return view.stamp(this);
     }
 
     public final void setStamp(Stamp stamp) {
@@ -99,7 +99,7 @@
     }
 
     public final JavaKind getStackKind() {
-        return stamp().getStackKind();
+        return stamp(NodeView.DEFAULT).getStackKind();
     }
 
     /**
@@ -197,9 +197,9 @@
 
     private boolean checkReplaceAtUsagesInvariants(Node other) {
         assert other == null || other instanceof ValueNode;
-        if (this.hasUsages() && !this.stamp().isEmpty() && !(other instanceof PhiNode) && other != null) {
-            assert ((ValueNode) other).stamp().getClass() == stamp().getClass() : "stamp have to be of same class";
-            boolean morePrecise = ((ValueNode) other).stamp().join(stamp()).equals(((ValueNode) other).stamp());
+        if (this.hasUsages() && !this.stamp(NodeView.DEFAULT).isEmpty() && !(other instanceof PhiNode) && other != null) {
+            assert ((ValueNode) other).stamp(NodeView.DEFAULT).getClass() == stamp(NodeView.DEFAULT).getClass() : "stamp have to be of same class";
+            boolean morePrecise = ((ValueNode) other).stamp(NodeView.DEFAULT).join(stamp(NodeView.DEFAULT)).equals(((ValueNode) other).stamp(NodeView.DEFAULT));
             assert morePrecise : "stamp can only get more precise " + toString(Verbosity.All) + " " +
                             other.toString(Verbosity.All);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -105,11 +105,11 @@
         for (ValueNode input : values()) {
             assert input != null;
             if (s == null) {
-                s = input.stamp();
+                s = input.stamp(NodeView.DEFAULT);
             } else {
-                if (!s.isCompatible(input.stamp())) {
+                if (!s.isCompatible(input.stamp(NodeView.DEFAULT))) {
                     fail("Phi Input Stamps are not compatible. Phi:%s inputs:%s", this,
-                                    CollectionsUtil.mapAndJoin(values(), x -> x.toString() + ":" + x.stamp(), ", "));
+                                    CollectionsUtil.mapAndJoin(values(), x -> x.toString() + ":" + x.stamp(NodeView.DEFAULT), ", "));
                 }
             }
         }
@@ -118,7 +118,7 @@
 
     @Override
     protected String valueDescription() {
-        return stamp().unrestricted().toString();
+        return stamp(NodeView.DEFAULT).unrestricted().toString();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValueProxyNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -41,7 +41,7 @@
     private final boolean loopPhiProxy;
 
     public ValueProxyNode(ValueNode value, LoopExitNode loopExit) {
-        super(TYPE, value.stamp(), loopExit);
+        super(TYPE, value.stamp(NodeView.DEFAULT), loopExit);
         this.value = value;
         loopPhiProxy = loopExit.loopBegin().isPhiAtMerge(value);
     }
@@ -53,7 +53,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(value.stamp());
+        return updateStamp(value.stamp(NodeView.DEFAULT));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -46,6 +47,23 @@
         super(TYPE, ArithmeticOpTable::getAbs, x);
     }
 
+    public static ValueNode create(ValueNode value, NodeView view) {
+        ValueNode synonym = findSynonym(value, view);
+        if (synonym != null) {
+            return synonym;
+        }
+        return new NegateNode(value);
+    }
+
+    protected static ValueNode findSynonym(ValueNode forValue, NodeView view) {
+        ArithmeticOpTable.UnaryOp<Abs> absOp = ArithmeticOpTable.forStamp(forValue.stamp(view)).getAbs();
+        ValueNode synonym = UnaryArithmeticNode.findSynonym(forValue, absOp);
+        if (synonym != null) {
+            return synonym;
+        }
+        return null;
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -51,21 +52,21 @@
         super(c, ArithmeticOpTable::getAdd, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp()).getAdd();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAdd();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
         if (x.isConstant() && !y.isConstant()) {
-            return canonical(null, op, y, x);
+            return canonical(null, op, y, x, view);
         } else {
-            return canonical(null, op, x, y);
+            return canonical(null, op, x, y, view);
         }
     }
 
-    private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY, NodeView view) {
         AddNode self = addNode;
         boolean associative = op.isAssociative();
         if (associative) {
@@ -91,16 +92,16 @@
             }
             if (associative && self != null) {
                 // canonicalize expressions like "(a + 1) + 2"
-                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
                 if (reassociated != self) {
                     return reassociated;
                 }
             }
         }
         if (forX instanceof NegateNode) {
-            return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue());
+            return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view);
         } else if (forY instanceof NegateNode) {
-            return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue());
+            return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
         }
         if (self == null) {
             self = (AddNode) new AddNode(forX, forY).maybeCommuteInputs();
@@ -125,7 +126,8 @@
             return new AddNode(forY, forX);
         }
         BinaryOp<Add> op = getOp(forX, forY);
-        return canonical(this, op, forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, op, forX, forY, view);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -51,14 +52,14 @@
         super(TYPE, ArithmeticOpTable::getAnd, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<And> op = ArithmeticOpTable.forStamp(x.stamp()).getAnd();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<And> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAnd();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
@@ -68,10 +69,11 @@
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
@@ -96,17 +98,17 @@
                         return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
                     }
                 }
-                IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+                IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
                 if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
                     // No bits are set which are outside the mask, so the mask will have no effect.
                     return forX;
                 }
             }
 
-            return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         if (forX instanceof NotNode && forY instanceof NotNode) {
-            return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue()));
+            return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
         }
         return self != null ? self : new AndNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ArithmeticOperation;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -60,13 +61,13 @@
     protected final SerializableBinaryFunction<OP> getOp;
 
     protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, SerializableBinaryFunction<OP> getOp, ValueNode x, ValueNode y) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp())).foldStamp(x.stamp(), y.stamp()), x, y);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
         this.getOp = getOp;
     }
 
     protected final BinaryOp<OP> getOp(ValueNode forX, ValueNode forY) {
-        ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp());
-        assert table.equals(ArithmeticOpTable.forStamp(forY.stamp()));
+        ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp(NodeView.DEFAULT));
+        assert table.equals(ArithmeticOpTable.forStamp(forY.stamp(NodeView.DEFAULT)));
         return getOp.apply(table);
     }
 
@@ -81,14 +82,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode result = tryConstantFold(getOp(forX, forY), forX, forY, stamp());
+        NodeView view = NodeView.from(tool);
+        ValueNode result = tryConstantFold(getOp(forX, forY), forX, forY, stamp(view), view);
         if (result != null) {
             return result;
         }
         return this;
     }
 
-    public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp) {
+    @SuppressWarnings("unused")
+    public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
             Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
             if (ret != null) {
@@ -100,32 +103,32 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        assert stampX.isCompatible(x.stamp()) && stampY.isCompatible(y.stamp());
+        assert stampX.isCompatible(x.stamp(NodeView.DEFAULT)) && stampY.isCompatible(y.stamp(NodeView.DEFAULT));
         return getArithmeticOp().foldStamp(stampX, stampY);
     }
 
-    public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(AddNode.create(v1, v2));
+    public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(AddNode.create(v1, v2, view));
     }
 
-    public static ValueNode add(ValueNode v1, ValueNode v2) {
-        return AddNode.create(v1, v2);
+    public static ValueNode add(ValueNode v1, ValueNode v2, NodeView view) {
+        return AddNode.create(v1, v2, view);
     }
 
-    public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(MulNode.create(v1, v2));
+    public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(MulNode.create(v1, v2, view));
     }
 
-    public static ValueNode mul(ValueNode v1, ValueNode v2) {
-        return MulNode.create(v1, v2);
+    public static ValueNode mul(ValueNode v1, ValueNode v2, NodeView view) {
+        return MulNode.create(v1, v2, view);
     }
 
-    public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.addOrUniqueWithInputs(SubNode.create(v1, v2));
+    public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2, NodeView view) {
+        return graph.addOrUniqueWithInputs(SubNode.create(v1, v2, view));
     }
 
-    public static ValueNode sub(ValueNode v1, ValueNode v2) {
-        return SubNode.create(v1, v2);
+    public static ValueNode sub(ValueNode v1, ValueNode v2, NodeView view) {
+        return SubNode.create(v1, v2, view);
     }
 
     private enum ReassociateMatch {
@@ -193,7 +196,7 @@
      * @param forY
      * @param forX
      */
-    public static ValueNode reassociate(BinaryArithmeticNode<?> node, NodePredicate criterion, ValueNode forX, ValueNode forY) {
+    public static ValueNode reassociate(BinaryArithmeticNode<?> node, NodePredicate criterion, ValueNode forX, ValueNode forY, NodeView view) {
         assert node.getOp(forX, forY).isAssociative();
         ReassociateMatch match1 = findReassociate(node, criterion);
         if (match1 == null) {
@@ -239,21 +242,21 @@
         if (node instanceof AddNode || node instanceof SubNode) {
             ValueNode associated;
             if (invertM1) {
-                associated = BinaryArithmeticNode.sub(m2, m1);
+                associated = BinaryArithmeticNode.sub(m2, m1, view);
             } else if (invertM2) {
-                associated = BinaryArithmeticNode.sub(m1, m2);
+                associated = BinaryArithmeticNode.sub(m1, m2, view);
             } else {
-                associated = BinaryArithmeticNode.add(m1, m2);
+                associated = BinaryArithmeticNode.add(m1, m2, view);
             }
             if (invertA) {
-                return BinaryArithmeticNode.sub(associated, a);
+                return BinaryArithmeticNode.sub(associated, a, view);
             }
             if (aSub) {
-                return BinaryArithmeticNode.sub(a, associated);
+                return BinaryArithmeticNode.sub(a, associated, view);
             }
-            return BinaryArithmeticNode.add(a, associated);
+            return BinaryArithmeticNode.add(a, associated, view);
         } else if (node instanceof MulNode) {
-            return BinaryArithmeticNode.mul(a, AddNode.mul(m1, m2));
+            return BinaryArithmeticNode.mul(a, AddNode.mul(m1, m2, view), view);
         } else if (node instanceof AndNode) {
             return new AndNode(a, new AndNode(m1, m2));
         } else if (node instanceof OrNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -26,6 +26,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 /**
@@ -73,7 +74,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/CompareNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 
@@ -91,7 +92,8 @@
         return null;
     }
 
-    public static LogicNode tryConstantFoldPrimitive(Condition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue) {
+    @SuppressWarnings("unused")
+    public static LogicNode tryConstantFoldPrimitive(Condition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue, NodeView view) {
         if (forX.asConstant() instanceof PrimitiveConstant && forY.asConstant() instanceof PrimitiveConstant) {
             return LogicConstantNode.forBoolean(condition.foldCondition((PrimitiveConstant) forX.asConstant(), (PrimitiveConstant) forY.asConstant(), unorderedIsTrue));
         }
@@ -110,27 +112,27 @@
 
     public abstract static class CompareOp {
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
             LogicNode constantCondition = tryConstantFold(condition, forX, forY, constantReflection, unorderedIsTrue);
             if (constantCondition != null) {
                 return constantCondition;
             }
             LogicNode result;
             if (forX.isConstant()) {
-                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forX.asConstant(), forY, true, unorderedIsTrue)) != null) {
+                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forX.asConstant(), forY, true, unorderedIsTrue, view)) != null) {
                     return result;
                 }
             } else if (forY.isConstant()) {
-                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forY.asConstant(), forX, false, unorderedIsTrue)) != null) {
+                if ((result = canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, forY.asConstant(), forX, false, unorderedIsTrue, view)) != null) {
                     return result;
                 }
             } else if (forX instanceof ConvertNode && forY instanceof ConvertNode) {
                 ConvertNode convertX = (ConvertNode) forX;
                 ConvertNode convertY = (ConvertNode) forY;
-                if (convertX.preservesOrder(condition) && convertY.preservesOrder(condition) && convertX.getValue().stamp().isCompatible(convertY.getValue().stamp())) {
+                if (convertX.preservesOrder(condition) && convertY.preservesOrder(condition) && convertX.getValue().stamp(view).isCompatible(convertY.getValue().stamp(view))) {
                     boolean supported = true;
-                    if (convertX.getValue().stamp() instanceof IntegerStamp) {
-                        IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp();
+                    if (convertX.getValue().stamp(view) instanceof IntegerStamp) {
+                        IntegerStamp intStamp = (IntegerStamp) convertX.getValue().stamp(view);
                         supported = smallestCompareWidth != null && intStamp.getBits() >= smallestCompareWidth;
                     }
 
@@ -141,7 +143,7 @@
                             // of the value.
                             return null;
                         }
-                        return duplicateModified(convertX.getValue(), convertY.getValue(), unorderedIsTrue);
+                        return duplicateModified(convertX.getValue(), convertY.getValue(), unorderedIsTrue, view);
                     }
                 }
             }
@@ -149,11 +151,11 @@
         }
 
         protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue) {
+                        Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) {
             if (nonConstant instanceof ConditionalNode) {
                 return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, mirrored ? condition.mirror() : condition, unorderedIsTrue);
             } else if (nonConstant instanceof NormalizeCompareNode) {
-                return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored);
+                return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored, view);
             } else if (nonConstant instanceof ConvertNode) {
                 ConvertNode convert = (ConvertNode) nonConstant;
                 boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage());
@@ -164,18 +166,18 @@
                 }
 
                 boolean supported = true;
-                if (convert.getValue().stamp() instanceof IntegerStamp) {
-                    IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp();
+                if (convert.getValue().stamp(view) instanceof IntegerStamp) {
+                    IntegerStamp intStamp = (IntegerStamp) convert.getValue().stamp(view);
                     supported = smallestCompareWidth != null && intStamp.getBits() > smallestCompareWidth;
                 }
 
                 if (supported) {
-                    ConstantNode newConstant = canonicalConvertConstant(constantReflection, metaAccess, options, condition, convert, constant);
+                    ConstantNode newConstant = canonicalConvertConstant(constantReflection, metaAccess, options, condition, convert, constant, view);
                     if (newConstant != null) {
                         if (mirrored) {
-                            return duplicateModified(newConstant, convert.getValue(), unorderedIsTrue);
+                            return duplicateModified(newConstant, convert.getValue(), unorderedIsTrue, view);
                         } else {
-                            return duplicateModified(convert.getValue(), newConstant, unorderedIsTrue);
+                            return duplicateModified(convert.getValue(), newConstant, unorderedIsTrue, view);
                         }
                     }
                 }
@@ -185,7 +187,7 @@
         }
 
         private static ConstantNode canonicalConvertConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Condition condition,
-                        ConvertNode convert, Constant constant) {
+                        ConvertNode convert, Constant constant, NodeView view) {
             if (convert.preservesOrder(condition, constant, constantReflection)) {
                 Constant reverseConverted = convert.reverse(constant, constantReflection);
                 if (reverseConverted != null && convert.convert(reverseConverted, constantReflection).equals(constant)) {
@@ -193,7 +195,7 @@
                         // We always want uncompressed constants
                         return null;
                     }
-                    return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, metaAccess);
+                    return ConstantNode.forConstant(convert.getValue().stamp(view), reverseConverted, metaAccess);
                 }
             }
             return null;
@@ -201,7 +203,7 @@
 
         @SuppressWarnings("unused")
         protected LogicNode optimizeNormalizeCompare(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+                        Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored, NodeView view) {
             throw new GraalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored);
         }
 
@@ -230,71 +232,71 @@
             return null;
         }
 
-        protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue);
+        protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue, NodeView view);
     }
 
-    public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
-        LogicNode result = createCompareNode(condition, x, y, constantReflection);
+    public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
+        LogicNode result = createCompareNode(condition, x, y, constantReflection, view);
         return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result);
     }
 
-    public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
+    public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
         assert x.getStackKind() == y.getStackKind();
         assert condition.isCanonical();
         assert !x.getStackKind().isNumericFloat();
 
         LogicNode comparison;
         if (condition == Condition.EQ) {
-            if (x.stamp() instanceof AbstractObjectStamp) {
-                comparison = ObjectEqualsNode.create(x, y, constantReflection);
-            } else if (x.stamp() instanceof AbstractPointerStamp) {
-                comparison = PointerEqualsNode.create(x, y);
+            if (x.stamp(view) instanceof AbstractObjectStamp) {
+                comparison = ObjectEqualsNode.create(x, y, constantReflection, view);
+            } else if (x.stamp(view) instanceof AbstractPointerStamp) {
+                comparison = PointerEqualsNode.create(x, y, view);
             } else {
                 assert x.getStackKind().isNumericInteger();
-                comparison = IntegerEqualsNode.create(x, y);
+                comparison = IntegerEqualsNode.create(x, y, view);
             }
         } else if (condition == Condition.LT) {
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerLessThanNode.create(x, y);
+            comparison = IntegerLessThanNode.create(x, y, view);
         } else {
             assert condition == Condition.BT;
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerBelowNode.create(x, y);
+            comparison = IntegerBelowNode.create(x, y, view);
         }
 
         return comparison;
     }
 
     public static LogicNode createCompareNode(StructuredGraph graph, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    Condition condition, ValueNode x, ValueNode y) {
-        LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y);
+                    Condition condition, ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y, view);
         return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result);
     }
 
     public static LogicNode createCompareNode(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    Condition condition, ValueNode x, ValueNode y) {
+                    Condition condition, ValueNode x, ValueNode y, NodeView view) {
         assert x.getStackKind() == y.getStackKind();
         assert condition.isCanonical();
         assert !x.getStackKind().isNumericFloat();
 
         LogicNode comparison;
         if (condition == Condition.EQ) {
-            if (x.stamp() instanceof AbstractObjectStamp) {
+            if (x.stamp(view) instanceof AbstractObjectStamp) {
                 assert smallestCompareWidth == null;
-                comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y);
-            } else if (x.stamp() instanceof AbstractPointerStamp) {
-                comparison = PointerEqualsNode.create(x, y);
+                comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, view);
+            } else if (x.stamp(view) instanceof AbstractPointerStamp) {
+                comparison = PointerEqualsNode.create(x, y, view);
             } else {
                 assert x.getStackKind().isNumericInteger();
-                comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+                comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
             }
         } else if (condition == Condition.LT) {
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+            comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
         } else {
             assert condition == Condition.BT;
             assert x.getStackKind().isNumericInteger();
-            comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y);
+            comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view);
         }
 
         return comparison;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -55,8 +56,8 @@
 
     public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class);
     @Input(InputType.Condition) LogicNode condition;
-    @Input ValueNode trueValue;
-    @Input ValueNode falseValue;
+    @Input(InputType.Value) ValueNode trueValue;
+    @Input(InputType.Value) ValueNode falseValue;
 
     public LogicNode condition() {
         return condition;
@@ -67,23 +68,23 @@
     }
 
     public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
-        super(TYPE, trueValue.stamp().meet(falseValue.stamp()));
-        assert trueValue.stamp().isCompatible(falseValue.stamp());
+        super(TYPE, trueValue.stamp(NodeView.DEFAULT).meet(falseValue.stamp(NodeView.DEFAULT)));
+        assert trueValue.stamp(NodeView.DEFAULT).isCompatible(falseValue.stamp(NodeView.DEFAULT));
         this.condition = condition;
         this.trueValue = trueValue;
         this.falseValue = falseValue;
     }
 
-    public static ValueNode create(LogicNode condition) {
-        return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()));
+    public static ValueNode create(LogicNode condition, NodeView view) {
+        return create(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()), view);
     }
 
-    public static ValueNode create(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
-        ValueNode synonym = findSynonym(condition, trueValue, falseValue);
+    public static ValueNode create(LogicNode condition, ValueNode trueValue, ValueNode falseValue, NodeView view) {
+        ValueNode synonym = findSynonym(condition, trueValue, falseValue, view);
         if (synonym != null) {
             return synonym;
         }
-        ValueNode result = canonicalizeConditional(condition, trueValue, falseValue, trueValue.stamp().meet(falseValue.stamp()));
+        ValueNode result = canonicalizeConditional(condition, trueValue, falseValue, trueValue.stamp(view).meet(falseValue.stamp(view)), view);
         if (result != null) {
             return result;
         }
@@ -92,7 +93,7 @@
 
     @Override
     public boolean inferStamp() {
-        Stamp valueStamp = trueValue.stamp().meet(falseValue.stamp());
+        Stamp valueStamp = trueValue.stamp(NodeView.DEFAULT).meet(falseValue.stamp(NodeView.DEFAULT));
         if (condition instanceof IntegerLessThanNode) {
             IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
             if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
@@ -130,12 +131,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode synonym = findSynonym(condition, trueValue(), falseValue());
+        NodeView view = NodeView.from(tool);
+        ValueNode synonym = findSynonym(condition, trueValue(), falseValue(), view);
         if (synonym != null) {
             return synonym;
         }
 
-        ValueNode result = canonicalizeConditional(condition, trueValue(), falseValue(), stamp);
+        ValueNode result = canonicalizeConditional(condition, trueValue(), falseValue(), stamp, view);
         if (result != null) {
             return result;
         }
@@ -143,7 +145,7 @@
         return this;
     }
 
-    public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp) {
+    public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp, NodeView view) {
         if (trueValue == falseValue) {
             return trueValue;
         }
@@ -156,12 +158,12 @@
             }
         }
 
-        if (trueValue.stamp() instanceof IntegerStamp) {
+        if (trueValue.stamp(view) instanceof IntegerStamp) {
             // check if the conditional is redundant
             if (condition instanceof IntegerLessThanNode) {
                 IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
-                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp();
-                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp();
+                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp(view);
+                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp(view);
                 if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
                     // return "x" for "x < y ? x : y" in case that we know "x <= y"
                     if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
@@ -182,25 +184,25 @@
                 long constFalseValue = falseValue.asJavaConstant().asLong();
                 if (condition instanceof IntegerEqualsNode) {
                     IntegerEqualsNode equals = (IntegerEqualsNode) condition;
-                    if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
-                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
+                    if (equals.getY().isConstant() && equals.getX().stamp(view) instanceof IntegerStamp) {
+                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp(view);
                         if (equalsXStamp.upMask() == 1) {
                             long equalsY = equals.getY().asJavaConstant().asLong();
                             if (equalsY == 0) {
                                 if (constTrueValue == 0 && constFalseValue == 1) {
                                     // return x when: x == 0 ? 0 : 1;
-                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
                                 } else if (constTrueValue == 1 && constFalseValue == 0) {
                                     // negate a boolean value via xor
-                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
                                 }
                             } else if (equalsY == 1) {
                                 if (constTrueValue == 1 && constFalseValue == 0) {
                                     // return x when: x == 1 ? 1 : 0;
-                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
                                 } else if (constTrueValue == 0 && constFalseValue == 1) {
                                     // negate a boolean value via xor
-                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
                                 }
                             }
                         }
@@ -211,10 +213,10 @@
                     // (value & 1) == 1 ? 1 : 0
                     IntegerTestNode integerTestNode = (IntegerTestNode) condition;
                     if (integerTestNode.getY().isConstant()) {
-                        assert integerTestNode.getX().stamp() instanceof IntegerStamp;
+                        assert integerTestNode.getX().stamp(view) instanceof IntegerStamp;
                         long testY = integerTestNode.getY().asJavaConstant().asLong();
                         if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
-                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
+                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY(), view), stamp, view);
                         }
                     }
                 }
@@ -231,7 +233,7 @@
                         if (trueValue instanceof AddNode) {
                             AddNode add = (AddNode) trueValue;
                             if (add.getX() == falseValue) {
-                                int bits = ((IntegerStamp) trueValue.stamp()).getBits();
+                                int bits = ((IntegerStamp) trueValue.stamp(NodeView.DEFAULT)).getBits();
                                 ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
                                 ValueNode and = new AndNode(shift, add.getY());
                                 return new AddNode(add.getX(), and);
@@ -245,10 +247,10 @@
         return null;
     }
 
-    private static ValueNode findSynonym(ValueNode condition, ValueNode trueValue, ValueNode falseValue) {
+    private static ValueNode findSynonym(ValueNode condition, ValueNode trueValue, ValueNode falseValue, NodeView view) {
         if (condition instanceof LogicNegationNode) {
             LogicNegationNode negated = (LogicNegationNode) condition;
-            return ConditionalNode.create(negated.getValue(), falseValue, trueValue);
+            return ConditionalNode.create(negated.getValue(), falseValue, trueValue, view);
         }
         if (condition instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition;
@@ -267,6 +269,6 @@
     }
 
     public ConditionalNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) {
-        this(createCompareNode(graph, condition, x, y, null));
+        this(createCompareNode(graph, condition, x, y, null, NodeView.DEFAULT));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -65,8 +66,8 @@
         this.op = op;
     }
 
-    public static ValueNode create(FloatConvert op, ValueNode input) {
-        ValueNode synonym = findSynonym(input, ArithmeticOpTable.forStamp(input.stamp()).getFloatConvert(op));
+    public static ValueNode create(FloatConvert op, ValueNode input, NodeView view) {
+        ValueNode synonym = findSynonym(input, ArithmeticOpTable.forStamp(input.stamp(view)).getFloatConvert(op));
         if (synonym != null) {
             return synonym;
         }
@@ -84,7 +85,7 @@
 
     @Override
     public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
-        FloatConvertOp reverse = ArithmeticOpTable.forStamp(stamp()).getFloatConvert(op.reverse());
+        FloatConvertOp reverse = ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)).getFloatConvert(op.reverse());
         return reverse.foldConstant(c);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -53,10 +54,10 @@
         assert stamp instanceof FloatStamp;
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp(view)).getDiv();
+        Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
         if (tryConstantFold != null) {
             return tryConstantFold;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatEqualsNode.java	Fri Dec 01 11:17:45 2017 -08