8192814: Update Graal
authordlong
Fri, 01 Dec 2017 11:17:45 -0800
changeset 48190 25cfedf27edc
parent 48189 acffbbe79871
child 48191 d8a62bea95d3
8192814: Update Graal Reviewed-by: kvn
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
--- 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");
+            }
+        }
+
+        // BigInteger intrinsics
+        if (!config.useMultiplyToLenIntrinsic()) {
+            if (isJDK9OrHigher()) {
+                add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[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");
+                add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
             }
         }
-        if (!config.useMultiplyToLenIntrinsic()) {
-            // Registration of the AES plugins is guarded by UseAESIntrinsics
-            if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
-                add(IGNORE, "java/math/BigInteger.multiplyToLen([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, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
+                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);
                         }
-                    }
-
-                    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 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);
+                    };
+                    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);
                         }
-                        if (block.getLoop() != null) {
-                            intervalInLoop.setBit(varNum, block.getLoop().getIndex());
+                    };
+
+                    // 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) {
-                        /*
-                         * 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 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
@@ -50,12 +51,12 @@
 
     public FloatEqualsNode(ValueNode x, ValueNode y) {
         super(TYPE, Condition.EQ, false, x, y);
-        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp : x.stamp() + " " + y.stamp();
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT) instanceof FloatStamp && y.stamp(NodeView.DEFAULT) instanceof FloatStamp : x.stamp(NodeView.DEFAULT) + " " + y.stamp(NodeView.DEFAULT);
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false, view);
         if (result != null) {
             return result;
         } else {
@@ -64,18 +65,18 @@
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y);
+                    ValueNode x, ValueNode y, NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public boolean isIdentityComparison() {
-        FloatStamp xStamp = (FloatStamp) x.stamp();
-        FloatStamp yStamp = (FloatStamp) y.stamp();
+        FloatStamp xStamp = (FloatStamp) x.stamp(NodeView.DEFAULT);
+        FloatStamp yStamp = (FloatStamp) y.stamp(NodeView.DEFAULT);
         /*
          * If both stamps have at most one 0.0 and it's the same 0.0 then this is an identity
          * comparison. FloatStamp isn't careful about tracking the presence of -0.0 so assume that
@@ -87,7 +88,8 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, unorderedIsTrue, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, unorderedIsTrue, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -98,13 +100,13 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
-            Stamp xStampGeneric = forX.stamp();
-            Stamp yStampGeneric = forY.stamp();
+            Stamp xStampGeneric = forX.stamp(view);
+            Stamp yStampGeneric = forY.stamp(view);
             if (xStampGeneric instanceof FloatStamp && yStampGeneric instanceof FloatStamp) {
                 FloatStamp xStamp = (FloatStamp) xStampGeneric;
                 FloatStamp yStamp = (FloatStamp) yStampGeneric;
@@ -118,10 +120,10 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatLessThanNode.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/FloatLessThanNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
@@ -49,12 +50,12 @@
 
     public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
         super(TYPE, Condition.LT, unorderedIsTrue, x, y);
-        assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp;
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT) instanceof FloatStamp && y.stamp(NodeView.DEFAULT) instanceof FloatStamp;
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.LT, x, y, unorderedIsTrue);
+    public static LogicNode create(ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.LT, x, y, unorderedIsTrue, view);
         if (result != null) {
             return result;
         }
@@ -62,17 +63,18 @@
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y, boolean unorderedIsTrue) {
-        LogicNode result = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.LT, unorderedIsTrue, x, y);
+                    ValueNode x, ValueNode y, boolean unorderedIsTrue, NodeView view) {
+        LogicNode result = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.LT, unorderedIsTrue, x, y, view);
         if (result != null) {
             return result;
         }
-        return create(x, y, unorderedIsTrue);
+        return create(x, y, unorderedIsTrue, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.LT, unorderedIsTrue, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.LT, unorderedIsTrue, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -83,8 +85,8 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
@@ -95,10 +97,10 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(NodeView.DEFAULT) instanceof FloatStamp && newY.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
                 return new FloatLessThanNode(newX, newY, unorderedIsTrue);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(NodeView.DEFAULT) instanceof IntegerStamp && newY.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 return new IntegerLessThanNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerBelowNode.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/IntegerBelowNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -45,25 +46,27 @@
 
     public IntegerBelowNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y, OP);
-        assert x.stamp() instanceof IntegerStamp;
-        assert y.stamp() instanceof IntegerStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        return OP.create(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        return OP.create(x, y, view);
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y,
+                    NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -72,8 +75,8 @@
 
     public static class BelowOp extends LowerOp {
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            assert newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp;
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            assert newX.stamp(NodeView.DEFAULT) instanceof IntegerStamp && newY.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
             return new IntegerBelowNode(newX, newY);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.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/IntegerConvertNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,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.spi.ArithmeticLIRLowerable;
@@ -61,12 +62,12 @@
 
     protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, SerializableIntegerConvertFunction<OP> getOp, SerializableIntegerConvertFunction<REV> getReverseOp, int inputBits,
                     int resultBits, ValueNode input) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp())).foldStamp(inputBits, resultBits, input.stamp()), input);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp(NodeView.DEFAULT))).foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
         this.getOp = getOp;
         this.getReverseOp = getReverseOp;
         this.inputBits = inputBits;
         this.resultBits = resultBits;
-        assert ((PrimitiveStamp) input.stamp()).getBits() == inputBits;
+        assert ((PrimitiveStamp) input.stamp(NodeView.DEFAULT)).getBits() == inputBits;
     }
 
     public int getInputBits() {
@@ -78,7 +79,7 @@
     }
 
     protected final IntegerConvertOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -93,19 +94,19 @@
 
     @Override
     public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
-        IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp()));
+        IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
         return reverse.foldConstant(getResultBits(), getInputBits(), c);
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return getArithmeticOp().foldStamp(inputBits, resultBits, newStamp);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp());
+        ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
         if (synonym != null) {
             return synonym;
         }
@@ -121,12 +122,12 @@
         return null;
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp) {
-        return convert(input, stamp, false);
+    public static ValueNode convert(ValueNode input, Stamp stamp, NodeView view) {
+        return convert(input, stamp, false, view);
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp, StructuredGraph graph) {
-        ValueNode convert = convert(input, stamp, false);
+    public static ValueNode convert(ValueNode input, Stamp stamp, StructuredGraph graph, NodeView view) {
+        ValueNode convert = convert(input, stamp, false, view);
         if (!convert.isAlive()) {
             assert !convert.isDeleted();
             convert = graph.addOrUniqueWithInputs(convert);
@@ -134,12 +135,12 @@
         return convert;
     }
 
-    public static ValueNode convertUnsigned(ValueNode input, Stamp stamp) {
-        return convert(input, stamp, true);
+    public static ValueNode convertUnsigned(ValueNode input, Stamp stamp, NodeView view) {
+        return convert(input, stamp, true, view);
     }
 
-    public static ValueNode convert(ValueNode input, Stamp stamp, boolean zeroExtend) {
-        IntegerStamp fromStamp = (IntegerStamp) input.stamp();
+    public static ValueNode convert(ValueNode input, Stamp stamp, boolean zeroExtend, NodeView view) {
+        IntegerStamp fromStamp = (IntegerStamp) input.stamp(view);
         IntegerStamp toStamp = (IntegerStamp) stamp;
 
         ValueNode result;
@@ -149,13 +150,13 @@
             result = new NarrowNode(input, fromStamp.getBits(), toStamp.getBits());
         } else if (zeroExtend) {
             // toStamp.getBits() > fromStamp.getBits()
-            result = ZeroExtendNode.create(input, toStamp.getBits());
+            result = ZeroExtendNode.create(input, toStamp.getBits(), view);
         } else {
             // toStamp.getBits() > fromStamp.getBits()
-            result = SignExtendNode.create(input, toStamp.getBits());
+            result = SignExtendNode.create(input, toStamp.getBits(), view);
         }
 
-        IntegerStamp resultStamp = (IntegerStamp) result.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) result.stamp(view);
         assert toStamp.getBits() == resultStamp.getBits();
         return result;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.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/IntegerDivRemNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+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;
@@ -59,7 +60,7 @@
 
         // Assigning canDeopt during constructor, because it must never change during lifetime of
         // the node.
-        this.canDeopt = ((IntegerStamp) getY().stamp()).contains(0);
+        this.canDeopt = ((IntegerStamp) getY().stamp(NodeView.DEFAULT)).contains(0);
     }
 
     public final Op getOp() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerEqualsNode.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/IntegerEqualsNode.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.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
@@ -59,8 +60,8 @@
         assert !y.getStackKind().isNumericFloat() && y.getStackKind() != JavaKind.Object;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = CompareNode.tryConstantFoldPrimitive(Condition.EQ, x, y, false, view);
         if (result != null) {
             return result;
         }
@@ -84,17 +85,19 @@
         return new IntegerEqualsNode(x, y).maybeCommuteInputs();
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, ValueNode x, ValueNode y,
+                    NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, Condition.EQ, false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -104,7 +107,7 @@
     public static class IntegerEqualsOp extends CompareOp {
         @Override
         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) {
             PrimitiveConstant primitive = (PrimitiveConstant) constant;
             ValueNode a = normalizeNode.getX();
             ValueNode b = normalizeNode.getY();
@@ -112,21 +115,21 @@
 
             if (cst == 0) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return FloatEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 } else {
-                    return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else if (cst == 1) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(b, a, !normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view);
                 }
             } else if (cst == -1) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(a, b, normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else {
                 return LogicConstantNode.contradiction();
@@ -134,12 +137,12 @@
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) {
+            } else if (newX.stamp(view) instanceof AbstractPointerStamp && newY.stamp(view) instanceof AbstractPointerStamp) {
                 return new IntegerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
@@ -147,10 +150,10 @@
 
         @Override
         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) {
             if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
                 return LogicConstantNode.tautology();
-            } else if (forX.stamp().alwaysDistinct(forY.stamp())) {
+            } else if (forX.stamp(view).alwaysDistinct(forY.stamp(view))) {
                 return LogicConstantNode.contradiction();
             }
 
@@ -174,19 +177,19 @@
                 }
                 if (v1 != null) {
                     assert v2 != null;
-                    return create(v1, v2);
+                    return create(v1, v2, view);
                 }
             }
 
-            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
         }
 
         @Override
         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 (constant instanceof PrimitiveConstant) {
                 PrimitiveConstant primitiveConstant = (PrimitiveConstant) constant;
-                IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp());
+                IntegerStamp nonConstantStamp = ((IntegerStamp) nonConstant.stamp(view));
                 if ((primitiveConstant.asLong() == 1 && nonConstantStamp.upperBound() == 1 && nonConstantStamp.lowerBound() == 0) ||
                                 (primitiveConstant.asLong() == -1 && nonConstantStamp.upperBound() == 0 && nonConstantStamp.lowerBound() == -1)) {
                     // nonConstant can only be 0 or 1 (respective -1), test against 0 instead of 1
@@ -194,15 +197,16 @@
                     // execution
                     // on specific platforms.
                     return LogicNegationNode.create(
-                                    IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0)));
+                                    IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, nonConstant, ConstantNode.forIntegerKind(nonConstant.getStackKind(), 0),
+                                                    view));
                 } else if (primitiveConstant.asLong() == 0) {
                     if (nonConstant instanceof AndNode) {
                         AndNode andNode = (AndNode) nonConstant;
                         return new IntegerTestNode(andNode.getX(), andNode.getY());
                     } else if (nonConstant instanceof SubNode) {
                         SubNode subNode = (SubNode) nonConstant;
-                        return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, subNode.getX(), subNode.getY());
-                    } else if (nonConstant instanceof ShiftNode && nonConstant.stamp() instanceof IntegerStamp) {
+                        return IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, subNode.getX(), subNode.getY(), view);
+                    } else if (nonConstant instanceof ShiftNode && nonConstant.stamp(view) instanceof IntegerStamp) {
                         if (nonConstant instanceof LeftShiftNode) {
                             LeftShiftNode shift = (LeftShiftNode) nonConstant;
                             if (shift.getY().isConstant()) {
@@ -217,7 +221,7 @@
                             }
                         } else if (nonConstant instanceof RightShiftNode) {
                             RightShiftNode shift = (RightShiftNode) nonConstant;
-                            if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp()).isPositive()) {
+                            if (shift.getY().isConstant() && ((IntegerStamp) shift.getX().stamp(view)).isPositive()) {
                                 int mask = shift.getShiftAmountMask();
                                 int amount = shift.getY().asJavaConstant().asInt() & mask;
                                 if (shift.getX().getStackKind() == JavaKind.Int) {
@@ -258,16 +262,16 @@
                     }
                 }
 
-                if (nonConstant instanceof XorNode && nonConstant.stamp() instanceof IntegerStamp) {
+                if (nonConstant instanceof XorNode && nonConstant.stamp(view) instanceof IntegerStamp) {
                     XorNode xorNode = (XorNode) nonConstant;
-                    if (xorNode.getY().isJavaConstant() && xorNode.getY().asJavaConstant().asLong() == 1 && ((IntegerStamp) xorNode.getX().stamp()).upMask() == 1) {
+                    if (xorNode.getY().isJavaConstant() && xorNode.getY().asJavaConstant().asLong() == 1 && ((IntegerStamp) xorNode.getX().stamp(view)).upMask() == 1) {
                         // x ^ 1 == 0 is the same as x == 1 if x in [0, 1]
                         // x ^ 1 == 1 is the same as x == 0 if x in [0, 1]
-                        return new IntegerEqualsNode(xorNode.getX(), ConstantNode.forIntegerStamp(xorNode.getX().stamp(), primitiveConstant.asLong() ^ 1));
+                        return new IntegerEqualsNode(xorNode.getX(), ConstantNode.forIntegerStamp(xorNode.getX().stamp(view), primitiveConstant.asLong() ^ 1));
                     }
                 }
             }
-            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue);
+            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.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/IntegerLessThanNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -40,6 +40,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.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -60,22 +61,23 @@
         assert !y.getStackKind().isNumericFloat() && y.getStackKind() != JavaKind.Object;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        return OP.create(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        return OP.create(x, y, view);
     }
 
     public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth,
-                    ValueNode x, ValueNode y) {
-        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y);
+                    ValueNode x, ValueNode y, NodeView view) {
+        LogicNode value = OP.canonical(constantReflection, metaAccess, options, smallestCompareWidth, OP.getCondition(), false, x, y, view);
         if (value != null) {
             return value;
         }
-        return create(x, y);
+        return create(x, y, view);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), OP.getCondition(), false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -98,11 +100,11 @@
 
     public static class LessThanOp extends LowerOp {
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof FloatStamp && newY.stamp() instanceof FloatStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof FloatStamp && newY.stamp(view) instanceof FloatStamp) {
                 return new FloatLessThanNode(newX, newY, unorderedIsTrue); // TODO: Is the last arg
                                                                            // supposed to be true?
-            } else if (newX.stamp() instanceof IntegerStamp && newY.stamp() instanceof IntegerStamp) {
+            } else if (newX.stamp(view) instanceof IntegerStamp && newY.stamp(view) instanceof IntegerStamp) {
                 return new IntegerLessThanNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
@@ -110,7 +112,7 @@
 
         @Override
         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) {
             PrimitiveConstant primitive = (PrimitiveConstant) constant;
             /* @formatter:off
              * a NC b < c  (not mirrored)
@@ -138,18 +140,18 @@
 
             if (cst == 0) {
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
-                    return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess);
+                    return FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, mirrored ^ normalizeNode.isUnorderedLess, view);
                 } else {
-                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b);
+                    return IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, a, b, view);
                 }
             } else if (cst == 1) {
                 // a <= b <=> !(a > b)
                 LogicNode compare;
                 if (normalizeNode.getX().getStackKind() == JavaKind.Double || normalizeNode.getX().getStackKind() == JavaKind.Float) {
                     // since we negate, we have to reverse the unordered result
-                    compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess);
+                    compare = FloatLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, mirrored == normalizeNode.isUnorderedLess, view);
                 } else {
-                    compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a);
+                    compare = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, b, a, view);
                 }
                 return LogicNegationNode.create(compare);
             } else if (cst <= -1) {
@@ -161,13 +163,13 @@
         }
 
         @Override
-        protected LogicNode findSynonym(ValueNode forX, ValueNode forY) {
-            LogicNode result = super.findSynonym(forX, forY);
+        protected LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.findSynonym(forX, forY, view);
             if (result != null) {
                 return result;
             }
-            if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
-                if (IntegerStamp.sameSign((IntegerStamp) forX.stamp(), (IntegerStamp) forY.stamp())) {
+            if (forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
+                if (IntegerStamp.sameSign((IntegerStamp) forX.stamp(view), (IntegerStamp) forY.stamp(view))) {
                     return new IntegerBelowNode(forX, forY);
                 }
             }
@@ -188,8 +190,8 @@
                 }
                 if (xx != null) {
                     assert yy != null;
-                    IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp();
-                    IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp();
+                    IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp(view);
+                    IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp(view);
                     long minValue = CodeUtil.minValue(xStamp.getBits());
                     long maxValue = CodeUtil.maxValue(xStamp.getBits());
 
@@ -203,10 +205,10 @@
                 }
             }
 
-            if (forX.stamp() instanceof IntegerStamp) {
-                assert forY.stamp() instanceof IntegerStamp;
-                int bits = ((IntegerStamp) forX.stamp()).getBits();
-                assert ((IntegerStamp) forY.stamp()).getBits() == bits;
+            if (forX.stamp(view) instanceof IntegerStamp) {
+                assert forY.stamp(view) instanceof IntegerStamp;
+                int bits = ((IntegerStamp) forX.stamp(view)).getBits();
+                assert ((IntegerStamp) forY.stamp(view)).getBits() == bits;
                 long min = OP.minValue(bits);
                 long xResidue = 0;
                 ValueNode left = null;
@@ -240,12 +242,12 @@
                             if (left == null) {
                                 left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
                             } else if (xResidue != 0) {
-                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue), view);
                             }
                             if (right == null) {
                                 right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
                             } else if (yResidue != 0) {
-                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
+                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue), view);
                             }
                             return new IntegerBelowNode(left, right);
                         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.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/IntegerLowerThanNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
@@ -76,12 +77,12 @@
             IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
             AddNode addNode = (AddNode) forY;
             IntegerStamp aStamp = null;
-            if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
+            if (addNode.getX() == forX && addNode.getY().stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 // x < x + a
-                aStamp = (IntegerStamp) addNode.getY().stamp();
-            } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
+                aStamp = (IntegerStamp) addNode.getY().stamp(NodeView.DEFAULT);
+            } else if (addNode.getY() == forX && addNode.getX().stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                 // x < a + x
-                aStamp = (IntegerStamp) addNode.getX().stamp();
+                aStamp = (IntegerStamp) addNode.getX().stamp(NodeView.DEFAULT);
             }
             if (aStamp != null) {
                 IntegerStamp result = getOp().getSucceedingStampForXLowerXPlusA(mirror, strict, aStamp);
@@ -117,12 +118,12 @@
     public abstract static class LowerOp extends CompareOp {
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
             if (result != null) {
                 return result;
             }
-            LogicNode synonym = findSynonym(forX, forY);
+            LogicNode synonym = findSynonym(forX, forY, view);
             if (synonym != null) {
                 return synonym;
             }
@@ -159,12 +160,12 @@
 
         protected abstract IntegerLowerThanNode createNode(ValueNode x, ValueNode y);
 
-        public LogicNode create(ValueNode x, ValueNode y) {
-            LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false);
+        public LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+            LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false, view);
             if (result != null) {
                 return result;
             } else {
-                result = findSynonym(x, y);
+                result = findSynonym(x, y, view);
                 if (result != null) {
                     return result;
                 }
@@ -172,47 +173,47 @@
             }
         }
 
-        protected LogicNode findSynonym(ValueNode forX, ValueNode forY) {
+        protected LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
             if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
                 return LogicConstantNode.contradiction();
             }
-            TriState fold = tryFold(forX.stamp(), forY.stamp());
+            TriState fold = tryFold(forX.stamp(view), forY.stamp(view));
             if (fold.isTrue()) {
                 return LogicConstantNode.tautology();
             } else if (fold.isFalse()) {
                 return LogicConstantNode.contradiction();
             }
-            if (forY.stamp() instanceof IntegerStamp) {
-                IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+            if (forY.stamp(view) instanceof IntegerStamp) {
+                IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
                 int bits = yStamp.getBits();
                 if (forX.isJavaConstant() && !forY.isConstant()) {
                     // bring the constant on the right
                     long xValue = forX.asJavaConstant().asLong();
                     if (xValue != maxValue(bits)) {
                         // c < x <=> !(c >= x) <=> !(x <= c) <=> !(x < c + 1)
-                        return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1)));
+                        return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1), view));
                     }
                 }
                 if (forY.isJavaConstant()) {
                     long yValue = forY.asJavaConstant().asLong();
                     if (yValue == maxValue(bits)) {
                         // x < MAX <=> x != MAX
-                        return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY));
+                        return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY, view));
                     }
                     if (yValue == minValue(bits) + 1) {
                         // x < MIN + 1 <=> x <= MIN <=> x == MIN
-                        return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)));
+                        return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)), view);
                     }
                 } else if (forY instanceof AddNode) {
                     AddNode addNode = (AddNode) forY;
-                    LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true, view);
                     if (canonical != null) {
                         return canonical;
                     }
                 }
                 if (forX instanceof AddNode) {
                     AddNode addNode = (AddNode) forX;
-                    LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false, view);
                     if (canonical != null) {
                         return canonical;
                     }
@@ -221,32 +222,32 @@
             return null;
         }
 
-        private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict) {
+        private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict, NodeView view) {
             // x < x + a
             IntegerStamp succeedingXStamp;
             boolean exact;
-            if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
-                IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp();
+            if (addNode.getX() == forX && addNode.getY().stamp(view) instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp(view);
                 succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
                 exact = aStamp.lowerBound() == aStamp.upperBound();
-            } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
-                IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp();
+            } else if (addNode.getY() == forX && addNode.getX().stamp(view) instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp(view);
                 succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
                 exact = aStamp.lowerBound() == aStamp.upperBound();
             } else {
                 return null;
             }
-            if (succeedingXStamp.join(forX.stamp()).isEmpty()) {
+            if (succeedingXStamp.join(forX.stamp(view)).isEmpty()) {
                 return LogicConstantNode.contradiction();
             } else if (exact && !succeedingXStamp.isEmpty()) {
                 int bits = succeedingXStamp.getBits();
                 if (compare(lowerBound(succeedingXStamp), minValue(bits)) > 0) {
                     assert upperBound(succeedingXStamp) == maxValue(bits);
                     // x must be in [L..MAX] <=> x >= L <=> !(x < L)
-                    return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp))));
+                    return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp)), view));
                 } else if (compare(upperBound(succeedingXStamp), maxValue(bits)) < 0) {
                     // x must be in [MIN..H] <=> x <= H <=> !(H < x)
-                    return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX));
+                    return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX, view));
                 }
             }
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerTestNode.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/IntegerTestNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.TriState;
@@ -52,12 +53,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         if (forX.isConstant() && forY.isConstant()) {
             return LogicConstantNode.forBoolean((forX.asJavaConstant().asLong() & forY.asJavaConstant().asLong()) == 0);
         }
-        if (forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
-            IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-            IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+        if (forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
+            IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
+            IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
             if ((xStamp.upMask() & yStamp.upMask()) == 0) {
                 return LogicConstantNode.tautology();
             } else if ((xStamp.downMask() & yStamp.downMask()) != 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.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/IsNullNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -77,7 +78,7 @@
     @Override
     public boolean verify() {
         assertTrue(getValue() != null, "is null input must not be null");
-        assertTrue(getValue().stamp() instanceof AbstractPointerStamp, "input must be a pointer not %s", getValue().stamp());
+        assertTrue(getValue().stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp, "input must be a pointer not %s", getValue().stamp(NodeView.DEFAULT));
         return super.verify();
     }
 
@@ -113,7 +114,7 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         ValueNode alias = tool.getAlias(getValue());
-        TriState fold = tryFold(alias.stamp());
+        TriState fold = tryFold(alias.stamp(NodeView.DEFAULT));
         if (fold != TriState.UNKNOWN) {
             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));
         }
@@ -122,7 +123,7 @@
     @Override
     public Stamp getSucceedingStampForValue(boolean negated) {
         // Ignore any more precise input stamp since canonicalization will skip through PiNodes
-        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp().unrestricted();
+        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp(NodeView.DEFAULT).unrestricted();
         return negated ? pointerStamp.asNonNull() : pointerStamp.asAlwaysNull();
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.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/LeftShiftNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,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;
 
@@ -45,10 +46,10 @@
         super(TYPE, ArithmeticOpTable::getShl, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        ArithmeticOpTable.ShiftOp<Shl> op = ArithmeticOpTable.forStamp(x.stamp()).getShl();
-        Stamp stamp = op.foldStamp(x.stamp(), (IntegerStamp) y.stamp());
-        ValueNode value = ShiftNode.canonical(op, stamp, x, y);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<Shl> op = ArithmeticOpTable.forStamp(x.stamp(view)).getShl();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
         if (value != null) {
             return value;
         }
@@ -63,7 +64,7 @@
             return ret;
         }
 
-        return canonical(this, getArithmeticOp(), stamp(), forX, forY);
+        return canonical(this, getArithmeticOp(), stamp(NodeView.DEFAULT), forX, forY);
     }
 
     private static ValueNode canonical(LeftShiftNode leftShiftNode, ArithmeticOpTable.ShiftOp<Shl> op, Stamp stamp, ValueNode forX, ValueNode forY) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.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/MulNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,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;
 
@@ -56,14 +57,14 @@
         super(c, ArithmeticOpTable::getMul, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Mul> op = ArithmeticOpTable.forStamp(x.stamp()).getMul();
-        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<Mul> op = ArithmeticOpTable.forStamp(x.stamp(view)).getMul();
+        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
@@ -83,10 +84,11 @@
             return new MulNode(forY, forX);
         }
         BinaryOp<Mul> op = getOp(forX, forY);
-        return canonical(this, op, stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, op, stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(MulNode self, BinaryOp<Mul> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(MulNode self, BinaryOp<Mul> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forY.isConstant()) {
             Constant c = forY.asConstant();
             if (op.isNeutral(c)) {
@@ -95,57 +97,64 @@
 
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
-
-                if (i == 0) {
-                    return ConstantNode.forIntegerStamp(stamp, 0);
-                } else if (i == 1) {
-                    return forX;
-                } else if (i == -1) {
-                    return NegateNode.create(forX);
-                } else if (i > 0) {
-                    if (CodeUtil.isPowerOf2(i)) {
-                        return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
-                    } else if (CodeUtil.isPowerOf2(i - 1)) {
-                        return AddNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i - 1))), forX);
-                    } else if (CodeUtil.isPowerOf2(i + 1)) {
-                        return SubNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))), forX);
-                    } else {
-                        int bitCount = Long.bitCount(i);
-                        long highestBitValue = Long.highestOneBit(i);
-                        if (bitCount == 2) {
-                            // e.g., 0b1000_0010
-                            long lowerBitValue = i - highestBitValue;
-                            assert highestBitValue > 0 && lowerBitValue > 0;
-                            ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(highestBitValue)));
-                            ValueNode right = lowerBitValue == 1 ? forX : new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(lowerBitValue)));
-                            return AddNode.create(left, right);
-                        } else {
-                            // e.g., 0b1111_1101
-                            int shiftToRoundUpToPowerOf2 = CodeUtil.log2(highestBitValue) + 1;
-                            long subValue = (1 << shiftToRoundUpToPowerOf2) - i;
-                            if (CodeUtil.isPowerOf2(subValue) && shiftToRoundUpToPowerOf2 < ((IntegerStamp) stamp).getBits()) {
-                                assert CodeUtil.log2(subValue) >= 1;
-                                ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(shiftToRoundUpToPowerOf2));
-                                ValueNode right = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(subValue)));
-                                return SubNode.create(left, right);
-                            }
-                        }
-                    }
-                } else if (i < 0) {
-                    if (CodeUtil.isPowerOf2(-i)) {
-                        return NegateNode.create(LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(-i))));
-                    }
+                ValueNode result = canonical(stamp, forX, i, view);
+                if (result != null) {
+                    return result;
                 }
             }
 
             if (op.isAssociative()) {
                 // canonicalize expressions like "(a * 1) * 2"
-                return reassociate(self != null ? self : (MulNode) new MulNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+                return reassociate(self != null ? self : (MulNode) new MulNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
             }
         }
         return self != null ? self : new MulNode(forX, forY).maybeCommuteInputs();
     }
 
+    public static ValueNode canonical(Stamp stamp, ValueNode forX, long i, NodeView view) {
+        if (i == 0) {
+            return ConstantNode.forIntegerStamp(stamp, 0);
+        } else if (i == 1) {
+            return forX;
+        } else if (i == -1) {
+            return NegateNode.create(forX, view);
+        } else if (i > 0) {
+            if (CodeUtil.isPowerOf2(i)) {
+                return new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
+            } else if (CodeUtil.isPowerOf2(i - 1)) {
+                return AddNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i - 1))), forX, view);
+            } else if (CodeUtil.isPowerOf2(i + 1)) {
+                return SubNode.create(new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))), forX, view);
+            } else {
+                int bitCount = Long.bitCount(i);
+                long highestBitValue = Long.highestOneBit(i);
+                if (bitCount == 2) {
+                    // e.g., 0b1000_0010
+                    long lowerBitValue = i - highestBitValue;
+                    assert highestBitValue > 0 && lowerBitValue > 0;
+                    ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(highestBitValue)));
+                    ValueNode right = lowerBitValue == 1 ? forX : new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(lowerBitValue)));
+                    return AddNode.create(left, right, view);
+                } else {
+                    // e.g., 0b1111_1101
+                    int shiftToRoundUpToPowerOf2 = CodeUtil.log2(highestBitValue) + 1;
+                    long subValue = (1 << shiftToRoundUpToPowerOf2) - i;
+                    if (CodeUtil.isPowerOf2(subValue) && shiftToRoundUpToPowerOf2 < ((IntegerStamp) stamp).getBits()) {
+                        assert CodeUtil.log2(subValue) >= 1;
+                        ValueNode left = new LeftShiftNode(forX, ConstantNode.forInt(shiftToRoundUpToPowerOf2));
+                        ValueNode right = new LeftShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(subValue)));
+                        return SubNode.create(left, right, view);
+                    }
+                }
+            }
+        } else if (i < 0) {
+            if (CodeUtil.isPowerOf2(-i)) {
+                return NegateNode.create(LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(-i)), view), view);
+            }
+        }
+        return null;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
         Value op1 = nodeValueMap.operand(getX());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.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/NarrowNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,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.NodeLIRBuilderTool;
 
@@ -48,21 +49,21 @@
     public static final NodeClass<NarrowNode> TYPE = NodeClass.create(NarrowNode.class);
 
     public NarrowNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < resultBits && resultBits <= PrimitiveStamp.getBits(input.stamp());
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < resultBits && resultBits <= PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT));
     }
 
     public NarrowNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getNarrow, ArithmeticOpTable::getSignExtend, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<Narrow> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getNarrow();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<Narrow> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getNarrow();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         } else {
@@ -77,6 +78,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
@@ -108,7 +110,7 @@
                 if (other instanceof SignExtendNode) {
                     // sxxx -(sign-extend)-> ssssssss sssssxxx -(narrow)-> sssssxxx
                     // ==> sxxx -(sign-extend)-> sssssxxx
-                    return SignExtendNode.create(other.getValue(), other.getInputBits(), getResultBits());
+                    return SignExtendNode.create(other.getValue(), other.getInputBits(), getResultBits(), view);
                 } else if (other instanceof ZeroExtendNode) {
                     // xxxx -(zero-extend)-> 00000000 00000xxx -(narrow)-> 0000xxxx
                     // ==> xxxx -(zero-extend)-> 0000xxxx
@@ -117,13 +119,13 @@
             }
         } else if (forValue instanceof AndNode) {
             AndNode andNode = (AndNode) forValue;
-            IntegerStamp yStamp = (IntegerStamp) andNode.getY().stamp();
-            IntegerStamp xStamp = (IntegerStamp) andNode.getX().stamp();
+            IntegerStamp yStamp = (IntegerStamp) andNode.getY().stamp(view);
+            IntegerStamp xStamp = (IntegerStamp) andNode.getX().stamp(view);
             long relevantMask = CodeUtil.mask(this.getResultBits());
             if ((relevantMask & yStamp.downMask()) == relevantMask) {
-                return create(andNode.getX(), this.getResultBits());
+                return create(andNode.getX(), this.getResultBits(), view);
             } else if ((relevantMask & xStamp.downMask()) == relevantMask) {
-                return create(andNode.getY(), this.getResultBits());
+                return create(andNode.getY(), this.getResultBits(), view);
             }
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.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/NegateNode.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.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.spi.StampInverter;
@@ -49,8 +50,8 @@
         super(TYPE, ArithmeticOpTable::getNeg, value);
     }
 
-    public static ValueNode create(ValueNode value) {
-        ValueNode synonym = findSynonym(value);
+    public static ValueNode create(ValueNode value, NodeView view) {
+        ValueNode synonym = findSynonym(value, view);
         if (synonym != null) {
             return synonym;
         }
@@ -66,8 +67,8 @@
         return this;
     }
 
-    protected static ValueNode findSynonym(ValueNode forValue) {
-        ArithmeticOpTable.UnaryOp<Neg> negOp = ArithmeticOpTable.forStamp(forValue.stamp()).getNeg();
+    protected static ValueNode findSynonym(ValueNode forValue, NodeView view) {
+        ArithmeticOpTable.UnaryOp<Neg> negOp = ArithmeticOpTable.forStamp(forValue.stamp(view)).getNeg();
         ValueNode synonym = UnaryArithmeticNode.findSynonym(forValue, negOp);
         if (synonym != null) {
             return synonym;
@@ -75,9 +76,9 @@
         if (forValue instanceof NegateNode) {
             return ((NegateNode) forValue).getValue();
         }
-        if (forValue instanceof SubNode && !(forValue.stamp() instanceof FloatStamp)) {
+        if (forValue instanceof SubNode && !(forValue.stamp(view) instanceof FloatStamp)) {
             SubNode sub = (SubNode) forValue;
-            return SubNode.create(sub.getY(), sub.getX());
+            return SubNode.create(sub.getY(), sub.getX(), view);
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NormalizeCompareNode.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/NormalizeCompareNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -86,7 +87,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode result = tryConstantFold(x, y, isUnorderedLess, stamp().getStackKind(), tool.getConstantReflection());
+        NodeView view = NodeView.from(tool);
+        ValueNode result = tryConstantFold(x, y, isUnorderedLess, stamp(view).getStackKind(), tool.getConstantReflection());
         if (result != null) {
             return result;
         }
@@ -100,7 +102,7 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 
     public boolean isUnorderedLess() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.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/NotNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -45,20 +45,31 @@
 
     public static final NodeClass<NotNode> TYPE = NodeClass.create(NotNode.class);
 
-    public NotNode(ValueNode x) {
+    protected NotNode(ValueNode x) {
         super(TYPE, ArithmeticOpTable::getNot, x);
     }
 
+    public static ValueNode create(ValueNode x) {
+        return canonicalize(null, x);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
-        if (forValue instanceof NotNode) {
-            return ((NotNode) forValue).getValue();
+        return canonicalize(this, forValue);
+    }
+
+    private static ValueNode canonicalize(NotNode node, ValueNode x) {
+        if (x instanceof NotNode) {
+            return ((NotNode) x).getValue();
         }
-        return this;
+        if (node != null) {
+            return node;
+        }
+        return new NotNode(x);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.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/ObjectEqualsNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.GetClassNode;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
@@ -58,16 +59,16 @@
 
     public ObjectEqualsNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        assert x.stamp() instanceof AbstractObjectStamp;
-        assert y.stamp() instanceof AbstractObjectStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
+    public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) {
         LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false);
         if (result != null) {
             return result;
         } else {
-            result = findSynonym(x, y);
+            result = findSynonym(x, y, view);
             if (result != null) {
                 return result;
             }
@@ -75,17 +76,18 @@
         }
     }
 
-    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, ValueNode x, ValueNode y) {
-        LogicNode result = OP.canonical(constantReflection, metaAccess, options, null, Condition.EQ, false, x, y);
+    public static LogicNode create(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = OP.canonical(constantReflection, metaAccess, options, null, Condition.EQ, false, x, y, view);
         if (result != null) {
             return result;
         }
-        return create(x, y, constantReflection);
+        return create(x, y, constantReflection, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -96,25 +98,25 @@
 
         @Override
         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) {
             ResolvedJavaType type = constantReflection.asJavaType(constant);
             if (type != null && nonConstant instanceof GetClassNode) {
                 GetClassNode getClassNode = (GetClassNode) nonConstant;
                 ValueNode object = getClassNode.getObject();
-                assert ((ObjectStamp) object.stamp()).nonNull();
+                assert ((ObjectStamp) object.stamp(view)).nonNull();
                 if (!type.isPrimitive() && (type.isConcrete() || type.isArray())) {
                     return InstanceOfNode.create(TypeReference.createExactTrusted(type), object);
                 }
                 return LogicConstantNode.forBoolean(false);
             }
-            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue);
+            return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
-            if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
+            if (newX.stamp(view) instanceof ObjectStamp && newY.stamp(view) instanceof ObjectStamp) {
                 return new ObjectEqualsNode(newX, newY);
-            } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) {
+            } else if (newX.stamp(view) instanceof AbstractPointerStamp && newY.stamp(view) instanceof AbstractPointerStamp) {
                 return new PointerEqualsNode(newX, newY);
             }
             throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.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/OrNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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;
@@ -50,27 +51,28 @@
         super(TYPE, ArithmeticOpTable::getOr, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
-        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<Or> op = ArithmeticOpTable.forStamp(x.stamp(view)).getOr();
+        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
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        return canonical(this, getOp(forX, forY), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(OrNode self, BinaryOp<Or> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
@@ -90,10 +92,10 @@
                     return ConstantNode.forIntegerStamp(stamp, mask);
                 }
             }
-            return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (OrNode) new OrNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         if (forX instanceof NotNode && forY instanceof NotNode) {
-            return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue()));
+            return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
         }
         return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/PointerEqualsNode.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/PointerEqualsNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
 import org.graalvm.compiler.nodes.extended.LoadMethodNode;
@@ -56,8 +57,8 @@
         this(TYPE, x, y);
     }
 
-    public static LogicNode create(ValueNode x, ValueNode y) {
-        LogicNode result = findSynonym(x, y);
+    public static LogicNode create(ValueNode x, ValueNode y, NodeView view) {
+        LogicNode result = findSynonym(x, y, view);
         if (result != null) {
             return result;
         }
@@ -66,13 +67,14 @@
 
     protected PointerEqualsNode(NodeClass<? extends PointerEqualsNode> c, ValueNode x, ValueNode y) {
         super(c, Condition.EQ, false, x, y);
-        assert x.stamp() instanceof AbstractPointerStamp;
-        assert y.stamp() instanceof AbstractPointerStamp;
+        assert x.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
+        assert y.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), Condition.EQ, false, forX, forY, view);
         if (value != null) {
             return value;
         }
@@ -111,31 +113,31 @@
 
         @Override
         public LogicNode canonical(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, Condition condition,
-                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY) {
-            LogicNode result = findSynonym(forX, forY);
+                        boolean unorderedIsTrue, ValueNode forX, ValueNode forY, NodeView view) {
+            LogicNode result = findSynonym(forX, forY, view);
             if (result != null) {
                 return result;
             }
             if (isAlwaysFailingVirtualDispatchTest(condition, forX, forY)) {
                 return LogicConstantNode.contradiction();
             }
-            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY);
+            return super.canonical(constantReflection, metaAccess, options, smallestCompareWidth, condition, unorderedIsTrue, forX, forY, view);
         }
 
         @Override
-        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue) {
+        protected CompareNode duplicateModified(ValueNode newX, ValueNode newY, boolean unorderedIsTrue, NodeView view) {
             return new PointerEqualsNode(newX, newY);
         }
     }
 
-    public static LogicNode findSynonym(ValueNode forX, ValueNode forY) {
+    public static LogicNode findSynonym(ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return LogicConstantNode.tautology();
-        } else if (forX.stamp().alwaysDistinct(forY.stamp())) {
+        } else if (forX.stamp(view).alwaysDistinct(forY.stamp(view))) {
             return LogicConstantNode.contradiction();
-        } else if (((AbstractPointerStamp) forX.stamp()).alwaysNull()) {
+        } else if (((AbstractPointerStamp) forX.stamp(view)).alwaysNull()) {
             return IsNullNode.create(forY);
-        } else if (((AbstractPointerStamp) forY.stamp()).alwaysNull()) {
+        } else if (((AbstractPointerStamp) forY.stamp(view)).alwaysNull()) {
             return IsNullNode.create(forX);
         } else {
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.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/ReinterpretNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,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.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -56,16 +57,24 @@
 
     public static final NodeClass<ReinterpretNode> TYPE = NodeClass.create(ReinterpretNode.class);
 
-    public ReinterpretNode(JavaKind to, ValueNode value) {
+    protected ReinterpretNode(JavaKind to, ValueNode value) {
         this(StampFactory.forKind(to), value);
     }
 
-    public ReinterpretNode(Stamp to, ValueNode value) {
-        super(TYPE, getReinterpretStamp(to, value.stamp()), value);
+    protected ReinterpretNode(Stamp to, ValueNode value) {
+        super(TYPE, getReinterpretStamp(to, value.stamp(NodeView.DEFAULT)), value);
         assert to instanceof ArithmeticStamp;
     }
 
-    private SerializableConstant evalConst(SerializableConstant c) {
+    public static ValueNode create(JavaKind to, ValueNode value, NodeView view) {
+        return create(StampFactory.forKind(to), value, view);
+    }
+
+    public static ValueNode create(Stamp to, ValueNode value, NodeView view) {
+        return canonical(null, to, value, view);
+    }
+
+    private static SerializableConstant evalConst(Stamp stamp, SerializableConstant c) {
         /*
          * We don't care about byte order here. Either would produce the correct result.
          */
@@ -73,7 +82,7 @@
         c.serialize(buffer);
 
         buffer.rewind();
-        SerializableConstant ret = ((ArithmeticStamp) stamp()).deserialize(buffer);
+        SerializableConstant ret = ((ArithmeticStamp) stamp).deserialize(buffer);
 
         assert !buffer.hasRemaining();
         return ret;
@@ -81,17 +90,22 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, this.stamp(view), forValue, view);
+    }
+
+    public static ValueNode canonical(ReinterpretNode node, Stamp forStamp, ValueNode forValue, NodeView view) {
         if (forValue.isConstant()) {
-            return ConstantNode.forConstant(stamp(), evalConst((SerializableConstant) forValue.asConstant()), null);
+            return ConstantNode.forConstant(forStamp, evalConst(forStamp, (SerializableConstant) forValue.asConstant()), null);
         }
-        if (stamp().isCompatible(forValue.stamp())) {
+        if (forStamp.isCompatible(forValue.stamp(view))) {
             return forValue;
         }
         if (forValue instanceof ReinterpretNode) {
             ReinterpretNode reinterpret = (ReinterpretNode) forValue;
-            return new ReinterpretNode(stamp(), reinterpret.getValue());
+            return new ReinterpretNode(forStamp, reinterpret.getValue());
         }
-        return this;
+        return node != null ? node : new ReinterpretNode(forStamp, forValue);
     }
 
     /**
@@ -269,12 +283,12 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(getReinterpretStamp(stamp(), getValue().stamp()));
+        return updateStamp(getReinterpretStamp(stamp(NodeView.DEFAULT), getValue().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
-        LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         builder.setResult(this, gen.emitReinterpret(kind, builder.operand(getValue())));
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.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/RemNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -25,10 +25,14 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Rem;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 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.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -39,7 +43,7 @@
 
     public static final NodeClass<RemNode> TYPE = NodeClass.create(RemNode.class);
 
-    public RemNode(ValueNode x, ValueNode y) {
+    protected RemNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
@@ -47,6 +51,16 @@
         super(c, ArithmeticOpTable::getRem, x, y);
     }
 
+    public static ValueNode create(ValueNode forX, ValueNode forY, NodeView view) {
+        BinaryOp<Rem> op = ArithmeticOpTable.forStamp(forX.stamp(view)).getRem();
+        Stamp stamp = op.foldStamp(forX.stamp(view), forY.stamp(view));
+        ConstantNode tryConstantFold = tryConstantFold(op, forX, forY, stamp, view);
+        if (tryConstantFold != null) {
+            return tryConstantFold;
+        }
+        return new RemNode(forX, forY);
+    }
+
     @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.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/RightShiftNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,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;
 
@@ -45,30 +46,31 @@
         super(TYPE, ArithmeticOpTable::getShr, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        ArithmeticOpTable.ShiftOp<Shr> op = ArithmeticOpTable.forStamp(x.stamp()).getShr();
-        Stamp stamp = op.foldStamp(x.stamp(), (IntegerStamp) y.stamp());
-        ValueNode value = ShiftNode.canonical(op, stamp, x, y);
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<Shr> op = ArithmeticOpTable.forStamp(x.stamp(view)).getShr();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
         if (value != null) {
             return value;
         }
 
-        return canonical(null, op, stamp, x, y);
+        return canonical(null, op, stamp, x, y, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, getArithmeticOp(), stamp(), forX, forY);
+        return canonical(this, getArithmeticOp(), stamp(view), forX, forY, view);
     }
 
-    private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(RightShiftNode rightShiftNode, ArithmeticOpTable.ShiftOp<Shr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         RightShiftNode self = rightShiftNode;
-        if (forX.stamp() instanceof IntegerStamp && ((IntegerStamp) forX.stamp()).isPositive()) {
+        if (forX.stamp(view) instanceof IntegerStamp && ((IntegerStamp) forX.stamp(view)).isPositive()) {
             return new UnsignedRightShiftNode(forX, forY);
         }
 
@@ -87,8 +89,8 @@
                     if (other instanceof RightShiftNode) {
                         int total = amount + otherAmount;
                         if (total != (total & mask)) {
-                            assert other.getX().stamp() instanceof IntegerStamp;
-                            IntegerStamp istamp = (IntegerStamp) other.getX().stamp();
+                            assert other.getX().stamp(view) instanceof IntegerStamp;
+                            IntegerStamp istamp = (IntegerStamp) other.getX().stamp(view);
 
                             if (istamp.isPositive()) {
                                 return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
@@ -131,7 +133,7 @@
              * are all equal to the sign bit of the input. That's equivalent to the condition that
              * the input is in the signed range of the narrow type.
              */
-            IntegerStamp inputStamp = (IntegerStamp) getX().stamp();
+            IntegerStamp inputStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT);
             return CodeUtil.minValue(resultBits) <= inputStamp.lowerBound() && inputStamp.upperBound() <= CodeUtil.maxValue(resultBits);
         } else {
             return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.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/ShiftNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,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.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 
@@ -64,13 +65,13 @@
      * @param s the second input value
      */
     protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, SerializableShiftFunction<OP> getOp, ValueNode x, ValueNode s) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp())).foldStamp(x.stamp(), (IntegerStamp) s.stamp()), x, s);
-        assert ((IntegerStamp) s.stamp()).getBits() == 32;
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
+        assert ((IntegerStamp) s.stamp(NodeView.DEFAULT)).getBits() == 32;
         this.getOp = getOp;
     }
 
     protected final ShiftOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -85,14 +86,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode valueNode = canonical(getOp(forX), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        ValueNode valueNode = canonical(getOp(forX), stamp(NodeView.DEFAULT), forX, forY, view);
         if (valueNode != null) {
             return valueNode;
         }
         return this;
     }
 
-    public static <OP> ValueNode canonical(ShiftOp<OP> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    @SuppressWarnings("unused")
+    public static <OP> ValueNode canonical(ShiftOp<OP> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
             JavaConstant amount = forY.asJavaConstant();
             assert amount.getJavaKind() == JavaKind.Int;
@@ -102,7 +105,7 @@
     }
 
     public int getShiftAmountMask() {
-        return getArithmeticOp().getShiftAmountMask(stamp());
+        return getArithmeticOp().getShiftAmountMask(stamp(NodeView.DEFAULT));
     }
 
     @Override
@@ -117,7 +120,7 @@
          * amount. We can narrow only if (y & wideMask) == (y & narrowMask) for all possible values
          * of y.
          */
-        IntegerStamp yStamp = (IntegerStamp) getY().stamp();
+        IntegerStamp yStamp = (IntegerStamp) getY().stamp(NodeView.DEFAULT);
         return (yStamp.upMask() & (wideMask & ~narrowMask)) == 0;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.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/SignExtendNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,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.NodeLIRBuilderTool;
 
@@ -46,25 +47,25 @@
     public static final NodeClass<SignExtendNode> TYPE = NodeClass.create(SignExtendNode.class);
 
     public SignExtendNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < PrimitiveStamp.getBits(input.stamp()) && PrimitiveStamp.getBits(input.stamp()) <= resultBits;
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
     }
 
     public SignExtendNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getSignExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<SignExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getSignExtend();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<SignExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getSignExtend();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         }
-        return canonical(null, input, inputBits, resultBits);
+        return canonical(null, input, inputBits, resultBits, view);
     }
 
     @Override
@@ -74,35 +75,36 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, forValue, getInputBits(), getResultBits());
+        return canonical(this, forValue, getInputBits(), getResultBits(), view);
     }
 
-    private static ValueNode canonical(SignExtendNode self, ValueNode forValue, int inputBits, int resultBits) {
+    private static ValueNode canonical(SignExtendNode self, ValueNode forValue, int inputBits, int resultBits, NodeView view) {
         if (forValue instanceof SignExtendNode) {
             // sxxx -(sign-extend)-> ssss sxxx -(sign-extend)-> ssssssss sssssxxx
             // ==> sxxx -(sign-extend)-> ssssssss sssssxxx
             SignExtendNode other = (SignExtendNode) forValue;
-            return SignExtendNode.create(other.getValue(), other.getInputBits(), resultBits);
+            return SignExtendNode.create(other.getValue(), other.getInputBits(), resultBits, view);
         } else if (forValue instanceof ZeroExtendNode) {
             ZeroExtendNode other = (ZeroExtendNode) forValue;
             if (other.getResultBits() > other.getInputBits()) {
                 // sxxx -(zero-extend)-> 0000 sxxx -(sign-extend)-> 00000000 0000sxxx
                 // ==> sxxx -(zero-extend)-> 00000000 0000sxxx
-                return ZeroExtendNode.create(other.getValue(), other.getInputBits(), resultBits);
+                return ZeroExtendNode.create(other.getValue(), other.getInputBits(), resultBits, view);
             }
         }
 
-        if (forValue.stamp() instanceof IntegerStamp) {
-            IntegerStamp inputStamp = (IntegerStamp) forValue.stamp();
+        if (forValue.stamp(view) instanceof IntegerStamp) {
+            IntegerStamp inputStamp = (IntegerStamp) forValue.stamp(view);
             if ((inputStamp.upMask() & (1L << (inputBits - 1))) == 0L) {
                 // 0xxx -(sign-extend)-> 0000 0xxx
                 // ==> 0xxx -(zero-extend)-> 0000 0xxx
-                return ZeroExtendNode.create(forValue, inputBits, resultBits);
+                return ZeroExtendNode.create(forValue, inputBits, resultBits, view);
             }
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.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/SignedDivNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,10 +24,12 @@
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -39,31 +41,42 @@
 
     public static final NodeClass<SignedDivNode> TYPE = NodeClass.create(SignedDivNode.class);
 
-    public SignedDivNode(ValueNode x, ValueNode y) {
+    protected SignedDivNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
     protected SignedDivNode(NodeClass<? extends SignedDivNode> c, ValueNode x, ValueNode y) {
-        super(c, IntegerStamp.OPS.getDiv().foldStamp(x.stamp(), y.stamp()), Op.DIV, Type.SIGNED, x, y);
+        super(c, IntegerStamp.OPS.getDiv().foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), Op.DIV, Type.SIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        return canonical(null, x, y, view);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(IntegerStamp.OPS.getDiv().foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getDiv().foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, view);
+    }
+
+    public static ValueNode canonical(SignedDivNode self, ValueNode forX, ValueNode forY, NodeView view) {
+        Stamp predictedStamp = IntegerStamp.OPS.getDiv().foldStamp(forX.stamp(NodeView.DEFAULT), forY.stamp(NodeView.DEFAULT));
+        Stamp stamp = self != null ? self.stamp(view) : predictedStamp;
         if (forX.isConstant() && forY.isConstant()) {
-            @SuppressWarnings("hiding")
             long y = forY.asJavaConstant().asLong();
             if (y == 0) {
-                return this; // this will trap, can not canonicalize
+                return self != null ? self : new SignedDivNode(forX, forY); // this will trap, can
+                                                                            // not canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
+            return ConstantNode.forIntegerStamp(stamp, forX.asJavaConstant().asLong() / y);
         } else if (forY.isConstant()) {
             long c = forY.asJavaConstant().asLong();
-            ValueNode v = canonical(forX, c);
+            ValueNode v = canonical(forX, c, view);
             if (v != null) {
                 return v;
             }
@@ -74,47 +87,47 @@
             SubNode integerSubNode = (SubNode) forX;
             if (integerSubNode.getY() instanceof SignedRemNode) {
                 SignedRemNode integerRemNode = (SignedRemNode) integerSubNode.getY();
-                if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.getX() == integerRemNode.getX() &&
+                if (integerSubNode.stamp(view).isCompatible(stamp) && integerRemNode.stamp(view).isCompatible(stamp) && integerSubNode.getX() == integerRemNode.getX() &&
                                 forY == integerRemNode.getY()) {
                     SignedDivNode sd = new SignedDivNode(integerSubNode.getX(), forY);
-                    sd.stateBefore = this.stateBefore;
+                    sd.stateBefore = self != null ? self.stateBefore : null;
                     return sd;
                 }
             }
         }
 
-        if (next() instanceof SignedDivNode) {
-            NodeClass<?> nodeClass = getNodeClass();
-            if (next().getClass() == this.getClass() && nodeClass.equalInputs(this, next()) && valueEquals(next())) {
-                return next();
+        if (self != null && self.next() instanceof SignedDivNode) {
+            NodeClass<?> nodeClass = self.getNodeClass();
+            if (self.next().getClass() == self.getClass() && nodeClass.equalInputs(self, self.next()) && self.valueEquals(self.next())) {
+                return self.next();
             }
         }
 
-        return this;
+        return self != null ? self : new SignedDivNode(forX, forY);
     }
 
-    public static ValueNode canonical(ValueNode forX, long c) {
+    public static ValueNode canonical(ValueNode forX, long c, NodeView view) {
         if (c == 1) {
             return forX;
         }
         if (c == -1) {
-            return NegateNode.create(forX);
+            return NegateNode.create(forX, view);
         }
         long abs = Math.abs(c);
-        if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+        if (CodeUtil.isPowerOf2(abs) && forX.stamp(view) instanceof IntegerStamp) {
             ValueNode dividend = forX;
-            IntegerStamp stampX = (IntegerStamp) forX.stamp();
+            IntegerStamp stampX = (IntegerStamp) forX.stamp(view);
             int log2 = CodeUtil.log2(abs);
             // no rounding if dividend is positive or if its low bits are always 0
             if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
-                int bits = PrimitiveStamp.getBits(forX.stamp());
+                int bits = PrimitiveStamp.getBits(forX.stamp(view));
                 RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
                 UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
-                dividend = BinaryArithmeticNode.add(dividend, round);
+                dividend = BinaryArithmeticNode.add(dividend, round, view);
             }
             RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
             if (c < 0) {
-                return NegateNode.create(shift);
+                return NegateNode.create(shift, view);
             }
             return shift;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.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/SignedRemNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -38,52 +40,63 @@
 
     public static final NodeClass<SignedRemNode> TYPE = NodeClass.create(SignedRemNode.class);
 
-    public SignedRemNode(ValueNode x, ValueNode y) {
+    protected SignedRemNode(ValueNode x, ValueNode y) {
         this(TYPE, x, y);
     }
 
     protected SignedRemNode(NodeClass<? extends SignedRemNode> c, ValueNode x, ValueNode y) {
-        super(c, IntegerStamp.OPS.getRem().foldStamp(x.stamp(), y.stamp()), Op.REM, Type.SIGNED, x, y);
+        super(c, IntegerStamp.OPS.getRem().foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), Op.REM, Type.SIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = IntegerStamp.OPS.getRem().foldStamp(x.stamp(view), y.stamp(view));
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(IntegerStamp.OPS.getRem().foldStamp(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getRem().foldStamp(getX().stamp(NodeView.DEFAULT), getY().stamp(NodeView.DEFAULT)));
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    private static ValueNode canonical(SignedRemNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
         if (forX.isConstant() && forY.isConstant()) {
-            @SuppressWarnings("hiding")
             long y = forY.asJavaConstant().asLong();
             if (y == 0) {
-                return this; // this will trap, can not canonicalize
+                return self != null ? self : new SignedRemNode(forX, forY); // this will trap, can
+                                                                            // not canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() % y);
-        } else if (forY.isConstant() && forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
+            return ConstantNode.forIntegerStamp(stamp, forX.asJavaConstant().asLong() % y);
+        } else if (forY.isConstant() && forX.stamp(view) instanceof IntegerStamp && forY.stamp(view) instanceof IntegerStamp) {
             long constY = forY.asJavaConstant().asLong();
-            IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-            IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+            IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
+            IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
             if (constY < 0 && constY != CodeUtil.minValue(yStamp.getBits())) {
-                return new SignedRemNode(forX, ConstantNode.forIntegerStamp(yStamp, -constY)).canonical(tool);
+                Stamp newStamp = IntegerStamp.OPS.getRem().foldStamp(forX.stamp(view), forY.stamp(view));
+                return canonical(null, forX, ConstantNode.forIntegerStamp(yStamp, -constY), newStamp, view);
             }
 
             if (constY == 1) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp, 0);
             } else if (CodeUtil.isPowerOf2(constY)) {
                 if (xStamp.isPositive()) {
                     // x & (y - 1)
-                    return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
+                    return new AndNode(forX, ConstantNode.forIntegerStamp(stamp, constY - 1));
                 } else if (xStamp.isNegative()) {
                     // -((-x) & (y - 1))
-                    return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+                    return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp, constY - 1)));
                 } else {
                     // x - ((x / y) << log2(y))
-                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY), ConstantNode.forInt(CodeUtil.log2(constY))));
+                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY, view), ConstantNode.forInt(CodeUtil.log2(constY)), view), view);
                 }
             }
         }
-        return this;
+        return self != null ? self : new SignedRemNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.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/SqrtNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,8 @@
 import org.graalvm.compiler.graph.NodeClass;
 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.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -42,10 +44,18 @@
 
     public static final NodeClass<SqrtNode> TYPE = NodeClass.create(SqrtNode.class);
 
-    public SqrtNode(ValueNode x) {
+    protected SqrtNode(ValueNode x) {
         super(TYPE, ArithmeticOpTable::getSqrt, x);
     }
 
+    public static ValueNode create(ValueNode x, NodeView view) {
+        if (x.isConstant()) {
+            ArithmeticOpTable.UnaryOp<Sqrt> op = ArithmeticOpTable.forStamp(x.stamp(view)).getSqrt();
+            return ConstantNode.forPrimitive(op.foldStamp(x.stamp(view)), op.foldConstant(x.asConstant()));
+        }
+        return new SqrtNode(x);
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
         nodeValueMap.setResult(this, gen.emitMathSqrt(nodeValueMap.operand(getValue())));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.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/SubNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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;
@@ -53,20 +54,20 @@
         super(c, ArithmeticOpTable::getSub, x, y);
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Sub> op = ArithmeticOpTable.forStamp(x.stamp()).getSub();
-        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<Sub> op = ArithmeticOpTable.forStamp(x.stamp(view)).getSub();
+        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);
     }
 
-    private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         SubNode self = subNode;
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            Constant zero = op.getZero(forX.stamp());
+            Constant zero = op.getZero(forX.stamp(view));
             if (zero != null) {
                 return ConstantNode.forPrimitive(stamp, zero);
             }
@@ -87,18 +88,18 @@
                 SubNode x = (SubNode) forX;
                 if (x.getX() == forY) {
                     // (a - b) - a
-                    return NegateNode.create(x.getY());
+                    return NegateNode.create(x.getY(), view);
                 }
             }
             if (forY instanceof AddNode) {
                 AddNode y = (AddNode) forY;
                 if (y.getX() == forX) {
                     // a - (a + b)
-                    return NegateNode.create(y.getY());
+                    return NegateNode.create(y.getY(), view);
                 }
                 if (y.getY() == forX) {
                     // b - (a + b)
-                    return NegateNode.create(y.getX());
+                    return NegateNode.create(y.getX(), view);
                 }
             } else if (forY instanceof SubNode) {
                 SubNode y = (SubNode) forY;
@@ -114,7 +115,7 @@
                 return forX;
             }
             if (associative && self != null) {
-                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
                 if (reassociated != self) {
                     return reassociated;
                 }
@@ -124,7 +125,7 @@
                 if (i < 0 || ((IntegerStamp) StampFactory.forKind(forY.getStackKind())).contains(-i)) {
                     // Adding a negative is more friendly to the backend since adds are
                     // commutative, so prefer add when it fits.
-                    return BinaryArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp, -i));
+                    return BinaryArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp, -i), view);
                 }
             }
         } else if (forX.isConstant()) {
@@ -135,30 +136,28 @@
                  * have to test for the neutral element of +, because we are doing this
                  * transformation: 0 - x == (-x) + 0 == -x.
                  */
-                return NegateNode.create(forY);
+                return NegateNode.create(forY, view);
             }
             if (associative && self != null) {
-                return reassociate(self, ValueNode.isConstantPredicate(), forX, forY);
+                return reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
             }
         }
         if (forY instanceof NegateNode) {
-            return BinaryArithmeticNode.add(forX, ((NegateNode) forY).getValue());
+            return BinaryArithmeticNode.add(forX, ((NegateNode) forY).getValue(), view);
         }
-        if (self == null) {
-            self = new SubNode(forX, forY);
-        }
-        return self;
+        return self != null ? self : new SubNode(forX, forY);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
         BinaryOp<Sub> op = getOp(forX, forY);
-        return canonical(this, op, stamp, forX, forY);
+        return canonical(this, op, stamp, forX, forY, view);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.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/UnaryArithmeticNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 
@@ -47,12 +48,12 @@
     protected final SerializableUnaryFunction<OP> getOp;
 
     protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, SerializableUnaryFunction<OP> getOp, ValueNode value) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp())).foldStamp(value.stamp()), value);
+        super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp(NodeView.DEFAULT))).foldStamp(value.stamp(NodeView.DEFAULT)), value);
         this.getOp = getOp;
     }
 
     protected final UnaryOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp()));
+        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
     }
 
     @Override
@@ -62,7 +63,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return getOp(getValue()).foldStamp(newStamp);
     }
 
@@ -77,7 +78,7 @@
 
     protected static <OP> ValueNode findSynonym(ValueNode forValue, UnaryOp<OP> op) {
         if (forValue.isConstant()) {
-            return ConstantNode.forPrimitive(op.foldStamp(forValue.stamp()), op.foldConstant(forValue.asConstant()));
+            return ConstantNode.forPrimitive(op.foldStamp(forValue.stamp(NodeView.DEFAULT)), op.foldConstant(forValue.asConstant()));
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.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/UnaryNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,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;
 
 /**
@@ -63,7 +64,7 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(foldStamp(value.stamp()));
+        return updateStamp(foldStamp(value.stamp(NodeView.DEFAULT)));
     }
 
     /**
@@ -74,6 +75,6 @@
      * @param newStamp
      */
     public Stamp foldStamp(Stamp newStamp) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.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/UnpackEndianHalfNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 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.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -52,7 +53,8 @@
         this.firstHalf = firstHalf;
     }
 
-    public static ValueNode create(ValueNode value, boolean firstHalf) {
+    @SuppressWarnings("unused")
+    public static ValueNode create(ValueNode value, boolean firstHalf, NodeView view) {
         if (value.isConstant() && value.asConstant().isDefaultForKind()) {
             return ConstantNode.defaultForKind(JavaKind.Int);
         }
@@ -84,7 +86,7 @@
         if ((byteOrder == ByteOrder.BIG_ENDIAN) == firstHalf) {
             result = graph().unique(new UnsignedRightShiftNode(result, ConstantNode.forInt(32, graph())));
         }
-        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph());
+        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph(), NodeView.DEFAULT);
         replaceAtUsagesAndDelete(result);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedDivNode.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/UnsignedDivNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -43,18 +45,30 @@
     }
 
     protected UnsignedDivNode(NodeClass<? extends UnsignedDivNode> c, ValueNode x, ValueNode y) {
-        super(c, x.stamp().unrestricted(), Op.DIV, Type.UNSIGNED, x, y);
+        super(c, x.stamp(NodeView.DEFAULT).unrestricted(), Op.DIV, Type.UNSIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = x.stamp(view).unrestricted();
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        int bits = ((IntegerStamp) stamp()).getBits();
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    @SuppressWarnings("unused")
+    private static ValueNode canonical(UnsignedDivNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
+        int bits = ((IntegerStamp) stamp).getBits();
         if (forX.isConstant() && forY.isConstant()) {
             long yConst = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (yConst == 0) {
-                return this; // this will trap, cannot canonicalize
+                return self != null ? self : new UnsignedDivNode(forX, forY); // this will trap,
+                                                                              // cannot canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), Long.divideUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
+            return ConstantNode.forIntegerStamp(stamp, Long.divideUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
         } else if (forY.isConstant()) {
             long c = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (c == 1) {
@@ -64,7 +78,7 @@
                 return new UnsignedRightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(c)));
             }
         }
-        return this;
+        return self != null ? self : new UnsignedDivNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRemNode.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/UnsignedRemNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,10 +23,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -43,27 +45,39 @@
     }
 
     protected UnsignedRemNode(NodeClass<? extends UnsignedRemNode> c, ValueNode x, ValueNode y) {
-        super(c, x.stamp().unrestricted(), Op.REM, Type.UNSIGNED, x, y);
+        super(c, x.stamp(NodeView.DEFAULT).unrestricted(), Op.REM, Type.UNSIGNED, x, y);
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        Stamp stamp = x.stamp(view).unrestricted();
+        return canonical(null, x, y, stamp, view);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        int bits = ((IntegerStamp) stamp()).getBits();
+        NodeView view = NodeView.from(tool);
+        return canonical(this, forX, forY, stamp(view), view);
+    }
+
+    @SuppressWarnings("unused")
+    public static ValueNode canonical(UnsignedRemNode self, ValueNode forX, ValueNode forY, Stamp stamp, NodeView view) {
+        int bits = ((IntegerStamp) stamp).getBits();
         if (forX.isConstant() && forY.isConstant()) {
             long yConst = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (yConst == 0) {
-                return this; // this will trap, cannot canonicalize
+                return self != null ? self : new UnsignedRemNode(forX, forY); // this will trap,
+                                                                              // cannot canonicalize
             }
-            return ConstantNode.forIntegerStamp(stamp(), Long.remainderUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
+            return ConstantNode.forIntegerStamp(stamp, Long.remainderUnsigned(CodeUtil.zeroExtend(forX.asJavaConstant().asLong(), bits), yConst));
         } else if (forY.isConstant()) {
             long c = CodeUtil.zeroExtend(forY.asJavaConstant().asLong(), bits);
             if (c == 1) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp, 0);
             } else if (CodeUtil.isPowerOf2(c)) {
-                return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), c - 1));
+                return new AndNode(forX, ConstantNode.forIntegerStamp(stamp, c - 1));
             }
         }
-        return this;
+        return self != null ? self : new UnsignedRemNode(forX, forY);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.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/UnsignedRightShiftNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -25,11 +25,13 @@
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.UShr;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 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.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -44,17 +46,34 @@
         super(TYPE, ArithmeticOpTable::getUShr, x, y);
     }
 
+    public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
+        ArithmeticOpTable.ShiftOp<UShr> op = ArithmeticOpTable.forStamp(x.stamp(view)).getUShr();
+        Stamp stamp = op.foldStamp(x.stamp(view), (IntegerStamp) y.stamp(view));
+        ValueNode value = ShiftNode.canonical(op, stamp, x, y, view);
+        if (value != null) {
+            return value;
+        }
+
+        return canonical(null, op, stamp, x, y, view);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
             return ret;
         }
 
+        return canonical(this, this.getArithmeticOp(), this.stamp(view), forX, forY, view);
+    }
+
+    @SuppressWarnings("unused")
+    private static ValueNode canonical(UnsignedRightShiftNode node, ArithmeticOpTable.ShiftOp<UShr> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (forY.isConstant()) {
             int amount = forY.asJavaConstant().asInt();
             int originalAmout = amount;
-            int mask = getShiftAmountMask();
+            int mask = op.getShiftAmountMask(stamp);
             amount &= mask;
             if (amount == 0) {
                 return forX;
@@ -66,14 +85,14 @@
                     if (other instanceof UnsignedRightShiftNode) {
                         int total = amount + otherAmount;
                         if (total != (total & mask)) {
-                            return ConstantNode.forIntegerKind(getStackKind(), 0);
+                            return ConstantNode.forIntegerKind(stamp.getStackKind(), 0);
                         }
                         return new UnsignedRightShiftNode(other.getX(), ConstantNode.forInt(total));
                     } else if (other instanceof LeftShiftNode && otherAmount == amount) {
-                        if (getStackKind() == JavaKind.Long) {
+                        if (stamp.getStackKind() == JavaKind.Long) {
                             return new AndNode(other.getX(), ConstantNode.forLong(-1L >>> amount));
                         } else {
-                            assert getStackKind() == JavaKind.Int;
+                            assert stamp.getStackKind() == JavaKind.Int;
                             return new AndNode(other.getX(), ConstantNode.forInt(-1 >>> amount));
                         }
                     }
@@ -83,7 +102,11 @@
                 return new UnsignedRightShiftNode(forX, ConstantNode.forInt(amount));
             }
         }
-        return this;
+
+        if (node != null) {
+            return node;
+        }
+        return new UnsignedRightShiftNode(forX, forY);
     }
 
     @Override
@@ -98,7 +121,7 @@
              * For unsigned right shifts, the narrow can be done before the shift if the cut off
              * bits are all zero.
              */
-            IntegerStamp inputStamp = (IntegerStamp) getX().stamp();
+            IntegerStamp inputStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT);
             return (inputStamp.upMask() & ~(resultBits - 1)) == 0;
         } else {
             return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.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/XorNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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;
@@ -48,17 +49,17 @@
 
     public XorNode(ValueNode x, ValueNode y) {
         super(TYPE, ArithmeticOpTable::getXor, x, y);
-        assert x.stamp().isCompatible(y.stamp());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Xor> op = ArithmeticOpTable.forStamp(x.stamp()).getXor();
-        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<Xor> op = ArithmeticOpTable.forStamp(x.stamp(view)).getXor();
+        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,12 +69,13 @@
             return ret;
         }
 
-        return canonical(this, getOp(forX, forY), stamp(), forX, forY);
+        NodeView view = NodeView.from(tool);
+        return canonical(this, getOp(forX, forY), stamp(NodeView.DEFAULT), forX, forY, view);
     }
 
-    private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp, ValueNode forX, ValueNode forY) {
+    private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forPrimitive(stamp, op.getZero(forX.stamp()));
+            return ConstantNode.forPrimitive(stamp, op.getZero(forX.stamp(view)));
         }
         if (forX.isConstant() && !forY.isConstant()) {
             return new XorNode(forY, forX);
@@ -91,7 +93,7 @@
                     return new NotNode(forX);
                 }
             }
-            return reassociate(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
         }
         return self != null ? self : new XorNode(forX, forY).maybeCommuteInputs();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.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/ZeroExtendNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,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.NodeLIRBuilderTool;
 
@@ -50,25 +51,25 @@
     public static final NodeClass<ZeroExtendNode> TYPE = NodeClass.create(ZeroExtendNode.class);
 
     public ZeroExtendNode(ValueNode input, int resultBits) {
-        this(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
-        assert 0 < PrimitiveStamp.getBits(input.stamp()) && PrimitiveStamp.getBits(input.stamp()) <= resultBits;
+        this(input, PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)), resultBits);
+        assert 0 < PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) && PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) <= resultBits;
     }
 
     public ZeroExtendNode(ValueNode input, int inputBits, int resultBits) {
         super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
     }
 
-    public static ValueNode create(ValueNode input, int resultBits) {
-        return create(input, PrimitiveStamp.getBits(input.stamp()), resultBits);
+    public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
+        return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view);
     }
 
-    public static ValueNode create(ValueNode input, int inputBits, int resultBits) {
-        IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp()).getZeroExtend();
-        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp()));
+    public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) {
+        IntegerConvertOp<ZeroExtend> signExtend = ArithmeticOpTable.forStamp(input.stamp(view)).getZeroExtend();
+        ValueNode synonym = findSynonym(signExtend, input, inputBits, resultBits, signExtend.foldStamp(inputBits, resultBits, input.stamp(view)));
         if (synonym != null) {
             return synonym;
         }
-        return canonical(null, input, inputBits, resultBits);
+        return canonical(null, input, inputBits, resultBits, view);
     }
 
     @Override
@@ -91,15 +92,16 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
             return ret;
         }
 
-        return canonical(this, forValue, getInputBits(), getResultBits());
+        return canonical(this, forValue, getInputBits(), getResultBits(), view);
     }
 
-    private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits) {
+    private static ValueNode canonical(ZeroExtendNode zeroExtendNode, ValueNode forValue, int inputBits, int resultBits, NodeView view) {
         ZeroExtendNode self = zeroExtendNode;
         if (forValue instanceof ZeroExtendNode) {
             // xxxx -(zero-extend)-> 0000 xxxx -(zero-extend)-> 00000000 0000xxxx
@@ -109,20 +111,20 @@
         }
         if (forValue instanceof NarrowNode) {
             NarrowNode narrow = (NarrowNode) forValue;
-            Stamp inputStamp = narrow.getValue().stamp();
+            Stamp inputStamp = narrow.getValue().stamp(view);
             if (inputStamp instanceof IntegerStamp) {
                 IntegerStamp istamp = (IntegerStamp) inputStamp;
-                long mask = CodeUtil.mask(PrimitiveStamp.getBits(narrow.stamp()));
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(narrow.stamp(view)));
 
                 if ((istamp.upMask() & ~mask) == 0) {
                     // The original value cannot change because of the narrow and zero extend.
 
                     if (istamp.getBits() < resultBits) {
                         // Need to keep the zero extend, skip the narrow.
-                        return create(narrow.getValue(), resultBits);
+                        return create(narrow.getValue(), resultBits, view);
                     } else if (istamp.getBits() > resultBits) {
                         // Need to keep the narrow, skip the zero extend.
-                        return NarrowNode.create(narrow.getValue(), resultBits);
+                        return NarrowNode.create(narrow.getValue(), resultBits, view);
                     } else {
                         assert istamp.getBits() == resultBits;
                         // Just return the original value.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/BlackholeNode.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/debug/BlackholeNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,6 +44,10 @@
         this.value = value;
     }
 
+    public ValueNode getValue() {
+        return value;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.getLIRGeneratorTool().emitBlackhole(gen.operand(value));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/OpaqueNode.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/debug/OpaqueNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,6 +27,7 @@
 
 import org.graalvm.compiler.graph.NodeClass;
 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;
@@ -39,7 +40,7 @@
     @Input protected ValueNode value;
 
     public OpaqueNode(ValueNode value) {
-        super(TYPE, value.stamp().unrestricted());
+        super(TYPE, value.stamp(NodeView.DEFAULT).unrestricted());
         this.value = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BoxNode.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/extended/BoxNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 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.java.MonitorIdNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -90,7 +91,7 @@
     }
 
     protected VirtualBoxingNode createVirtualBoxingNode() {
-        return new VirtualBoxingNode(StampTool.typeOrNull(stamp()), boxingKind);
+        return new VirtualBoxingNode(StampTool.typeOrNull(stamp(NodeView.DEFAULT)), boxingKind);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.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/extended/BranchProbabilityNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
@@ -67,7 +68,7 @@
     @Input ValueNode condition;
 
     public BranchProbabilityNode(ValueNode probability, ValueNode condition) {
-        super(TYPE, condition.stamp());
+        super(TYPE, condition.stamp(NodeView.DEFAULT));
         this.probability = probability;
         this.condition = condition;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.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/extended/FixedValueAnchorNode.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.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;
@@ -46,7 +47,7 @@
     }
 
     protected FixedValueAnchorNode(NodeClass<? extends FixedValueAnchorNode> c, ValueNode object) {
-        super(c, object.stamp());
+        super(c, object.stamp(NodeView.DEFAULT));
         this.object = object;
     }
 
@@ -63,7 +64,7 @@
     @Override
     public boolean inferStamp() {
         if (predefinedStamp == null) {
-            return updateStamp(object.stamp());
+            return updateStamp(object.stamp(NodeView.DEFAULT));
         } else {
             return false;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/GetClassNode.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/extended/GetClassNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.spi.Lowerable;
@@ -60,7 +61,7 @@
     public GetClassNode(Stamp stamp, ValueNode object) {
         super(TYPE, stamp);
         this.object = object;
-        assert ((ObjectStamp) object.stamp()).nonNull();
+        assert ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
     }
 
     @Override
@@ -68,9 +69,9 @@
         tool.getLowerer().lower(this, tool);
     }
 
-    public static ValueNode tryFold(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ValueNode object) {
-        if (metaAccess != null && object != null && object.stamp() instanceof ObjectStamp) {
-            ObjectStamp objectStamp = (ObjectStamp) object.stamp();
+    public static ValueNode tryFold(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, NodeView view, ValueNode object) {
+        if (metaAccess != null && object != null && object.stamp(view) instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) object.stamp(view);
             if (objectStamp.isExactType()) {
                 return ConstantNode.forConstant(constantReflection.asJavaClass(objectStamp.type()), metaAccess);
             }
@@ -80,7 +81,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode folded = tryFold(tool.getMetaAccess(), tool.getConstantReflection(), getObject());
+        NodeView view = NodeView.from(tool);
+        ValueNode folded = tryFold(tool.getMetaAccess(), tool.getConstantReflection(), view, getObject());
         return folded == null ? this : folded;
     }
 
@@ -90,7 +92,7 @@
         if (alias instanceof VirtualObjectNode) {
             VirtualObjectNode virtual = (VirtualObjectNode) alias;
             Constant javaClass = tool.getConstantReflectionProvider().asJavaClass(virtual.type());
-            tool.replaceWithValue(ConstantNode.forConstant(stamp(), javaClass, tool.getMetaAccessProvider(), graph()));
+            tool.replaceWithValue(ConstantNode.forConstant(stamp(NodeView.DEFAULT), javaClass, tool.getMetaAccessProvider(), graph()));
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.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/extended/IntegerSwitchNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -43,6 +43,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
@@ -70,7 +71,7 @@
         assert keySuccessors.length == keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert value.stamp() instanceof PrimitiveStamp && value.stamp().getStackKind().isNumericInteger();
+        assert value.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger();
         assert assertSorted();
     }
 
@@ -135,6 +136,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        NodeView view = NodeView.from(tool);
         if (blockSuccessorCount() == 1) {
             tool.addToWorkList(defaultSuccessor());
             graph().removeSplitPropagate(this, defaultSuccessor());
@@ -142,7 +144,7 @@
             killOtherSuccessors(tool, successorIndexAtKey(value().asJavaConstant().asInt()));
         } else if (tryOptimizeEnumSwitch(tool)) {
             return;
-        } else if (tryRemoveUnreachableKeys(tool, value().stamp())) {
+        } else if (tryRemoveUnreachableKeys(tool, value().stamp(view))) {
             return;
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadHubNode.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/extended/LoadHubNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.spi.Lowerable;
@@ -61,8 +62,8 @@
     }
 
     private static Stamp hubStamp(StampProvider stampProvider, ValueNode value) {
-        assert value.stamp() instanceof ObjectStamp;
-        return stampProvider.createHubStamp(((ObjectStamp) value.stamp()));
+        assert value.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
+        return stampProvider.createHubStamp(((ObjectStamp) value.stamp(NodeView.DEFAULT)));
     }
 
     public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
@@ -91,9 +92,10 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (!GeneratePIC.getValue(tool.getOptions())) {
+            NodeView view = NodeView.from(tool);
             MetaAccessProvider metaAccess = tool.getMetaAccess();
             ValueNode curValue = getValue();
-            ValueNode newNode = findSynonym(curValue, stamp(), metaAccess, tool.getConstantReflection());
+            ValueNode newNode = findSynonym(curValue, stamp(view), metaAccess, tool.getConstantReflection());
             if (newNode != null) {
                 return newNode;
             }
@@ -117,7 +119,7 @@
             ValueNode alias = tool.getAlias(getValue());
             TypeReference type = StampTool.typeReferenceOrNull(alias);
             if (type != null && type.isExact()) {
-                tool.replaceWithValue(ConstantNode.forConstant(stamp(), tool.getConstantReflectionProvider().asObjectHub(type.getType()), tool.getMetaAccessProvider(), graph()));
+                tool.replaceWithValue(ConstantNode.forConstant(stamp(NodeView.DEFAULT), tool.getConstantReflectionProvider().asObjectHub(type.getType()), tool.getMetaAccessProvider(), graph()));
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/LoadMethodNode.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/extended/LoadMethodNode.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.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -96,8 +97,9 @@
                 Assumptions assumptions = graph().getAssumptions();
                 AssumptionResult<ResolvedJavaMethod> resolvedMethod = type.getType().findUniqueConcreteMethod(method);
                 if (resolvedMethod != null && resolvedMethod.canRecordTo(assumptions) && !type.getType().isInterface() && method.getDeclaringClass().isAssignableFrom(type.getType())) {
+                    NodeView view = NodeView.from(tool);
                     resolvedMethod.recordTo(assumptions);
-                    return ConstantNode.forConstant(stamp(), resolvedMethod.getResult().getEncoding(), tool.getMetaAccess());
+                    return ConstantNode.forConstant(stamp(view), resolvedMethod.getResult().getEncoding(), tool.getMetaAccess());
                 }
             }
         }
@@ -123,9 +125,9 @@
              * This really represent a misuse of LoadMethod since we're loading from a class which
              * isn't known to implement the original method but for now at least fold it away.
              */
-            return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, null);
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), JavaConstant.NULL_POINTER, null);
         } else {
-            return ConstantNode.forConstant(stamp(), newMethod.getEncoding(), tool.getMetaAccess());
+            return ConstantNode.forConstant(stamp(NodeView.DEFAULT), newMethod.getEncoding(), tool.getMetaAccess());
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.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/extended/RawLoadNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.ReinterpretNode;
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
@@ -103,14 +104,14 @@
                     JavaKind entryKind = virtual.entryKind(entryIndex);
                     if (entry.getStackKind() == getStackKind() || entryKind == accessKind()) {
 
-                        if (!(entry.stamp().isCompatible(stamp()))) {
-                            if (entry.stamp() instanceof PrimitiveStamp && stamp instanceof PrimitiveStamp) {
+                        if (!(entry.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT)))) {
+                            if (entry.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && stamp instanceof PrimitiveStamp) {
                                 PrimitiveStamp p1 = (PrimitiveStamp) stamp;
-                                PrimitiveStamp p2 = (PrimitiveStamp) entry.stamp();
+                                PrimitiveStamp p2 = (PrimitiveStamp) entry.stamp(NodeView.DEFAULT);
                                 int width1 = p1.getBits();
                                 int width2 = p2.getBits();
                                 if (width1 == width2) {
-                                    Node replacement = new ReinterpretNode(p2, entry);
+                                    Node replacement = ReinterpretNode.create(p2, entry, NodeView.DEFAULT);
                                     tool.replaceWith((ValueNode) replacement);
                                     return;
                                 } else {
@@ -141,11 +142,12 @@
                     if (arrayConstant != null) {
                         int stableDimension = objectConstant.getStableDimension();
                         if (stableDimension > 0) {
+                            NodeView view = NodeView.from(tool);
                             long constantOffset = offset().asJavaConstant().asLong();
-                            Constant constant = stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), arrayConstant, constantOffset);
+                            Constant constant = stamp(view).readConstant(tool.getConstantReflection().getMemoryAccessProvider(), arrayConstant, constantOffset);
                             boolean isDefaultStable = objectConstant.isDefaultStable();
                             if (constant != null && (isDefaultStable || !constant.isDefaultForKind())) {
-                                return ConstantNode.forConstant(stamp(), constant, stableDimension - 1, isDefaultStable, tool.getMetaAccess());
+                                return ConstantNode.forConstant(stamp(view), constant, stableDimension - 1, isDefaultStable, tool.getMetaAccess());
                             }
                         }
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/SwitchNode.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/extended/SwitchNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -46,6 +46,7 @@
 import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ControlSplitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.Constant;
@@ -79,7 +80,8 @@
      */
     protected SwitchNode(NodeClass<? extends SwitchNode> c, ValueNode value, AbstractBeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
         super(c, StampFactory.forVoid());
-        assert value.stamp().getStackKind().isNumericInteger() || value.stamp() instanceof AbstractPointerStamp : value.stamp() + " key not supported by SwitchNode";
+        assert value.stamp(NodeView.DEFAULT).getStackKind().isNumericInteger() || value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp : value.stamp(NodeView.DEFAULT) +
+                        " key not supported by SwitchNode";
         assert keySuccessors.length == keyProbabilities.length;
         this.successors = new NodeSuccessorList<>(this, successors);
         this.value = value;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.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/graphbuilderconf/GraphBuilderContext.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -118,7 +119,7 @@
     }
 
     default ValueNode addNonNullCast(ValueNode value) {
-        AbstractPointerStamp valueStamp = (AbstractPointerStamp) value.stamp();
+        AbstractPointerStamp valueStamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT);
         if (valueStamp.nonNull()) {
             return value;
         } else {
@@ -277,7 +278,7 @@
     default ValueNode nullCheckedValue(ValueNode value, DeoptimizationAction action) {
         if (!StampTool.isPointerNonNull(value)) {
             LogicNode condition = getGraph().unique(IsNullNode.create(value));
-            ObjectStamp receiverStamp = (ObjectStamp) value.stamp();
+            ObjectStamp receiverStamp = (ObjectStamp) value.stamp(NodeView.DEFAULT);
             Stamp stamp = receiverStamp.join(objectNonNull());
             FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, NullCheckException, action, true));
             ValueNode nonNullReceiver = getGraph().addOrUniqueWithInputs(PiNode.create(value, stamp, fixedGuard));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractCompareAndSwapNode.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/java/AbstractCompareAndSwapNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -88,6 +89,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return expectedValue.stamp().meet(newValue.stamp()).unrestricted();
+        return expectedValue.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)).unrestricted();
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/DynamicNewInstanceNode.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/java/DynamicNewInstanceNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -59,7 +60,7 @@
     protected DynamicNewInstanceNode(NodeClass<? extends DynamicNewInstanceNode> c, ValueNode clazz, boolean fillContents, FrameState stateBefore) {
         super(c, StampFactory.objectNonNull(), fillContents, stateBefore);
         this.clazz = clazz;
-        assert ((ObjectStamp) clazz.stamp()).nonNull();
+        assert ((ObjectStamp) clazz.stamp(NodeView.DEFAULT)).nonNull();
     }
 
     public ValueNode getInstanceType() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ExceptionObjectNode.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/java/ExceptionObjectNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodes.BeginStateSplitNode;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.KillingBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -79,7 +80,7 @@
              */
             LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
             AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
-            LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp()));
+            LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
 
             loadException.setStateAfter(stateAfter());
             replaceAtUsages(InputType.Value, loadException);
@@ -93,7 +94,7 @@
     @Override
     public boolean verify() {
         assertTrue(stateAfter() != null, "an exception handler needs a frame state");
-        assertTrue(stateAfter().stackSize() == 1 && stateAfter().stackAt(0).stamp().getStackKind() == JavaKind.Object,
+        assertTrue(stateAfter().stackSize() == 1 && stateAfter().stackAt(0).stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object,
                         "an exception handler's frame state must have only the exception on the stack");
         return super.verify();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.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/java/InstanceOfNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,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.UnaryOpLogicNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.IsNullNode;
@@ -92,7 +93,7 @@
     }
 
     public static LogicNode createHelper(ObjectStamp checkedStamp, ValueNode object, JavaTypeProfile profile, AnchoringNode anchor) {
-        LogicNode synonym = findSynonym(checkedStamp, object);
+        LogicNode synonym = findSynonym(checkedStamp, object, NodeView.DEFAULT);
         if (synonym != null) {
             return synonym;
         } else {
@@ -107,7 +108,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        LogicNode synonym = findSynonym(checkedStamp, forValue);
+        NodeView view = NodeView.from(tool);
+        LogicNode synonym = findSynonym(checkedStamp, forValue, view);
         if (synonym != null) {
             return synonym;
         } else {
@@ -115,8 +117,8 @@
         }
     }
 
-    public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object) {
-        ObjectStamp inputStamp = (ObjectStamp) object.stamp();
+    public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object, NodeView view) {
+        ObjectStamp inputStamp = (ObjectStamp) object.stamp(view);
         ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
 
         if (joinedStamp.isEmpty()) {
@@ -158,7 +160,7 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         ValueNode alias = tool.getAlias(getValue());
-        TriState fold = tryFold(alias.stamp());
+        TriState fold = tryFold(alias.stamp(NodeView.DEFAULT));
         if (fold != TriState.UNKNOWN) {
             tool.replaceWithValue(LogicConstantNode.forBoolean(fold.isTrue(), graph()));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.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/java/LoadFieldNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -98,7 +99,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) {
-        if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) {
+        NodeView view = NodeView.from(tool);
+        if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp(view)))) {
             return null;
         }
         return canonical(this, StampPair.create(stamp, uncheckedStamp), forObject, field, tool.getConstantFieldProvider(),
@@ -178,10 +180,10 @@
             int fieldIndex = ((VirtualInstanceNode) alias).fieldIndex(field());
             if (fieldIndex != -1) {
                 ValueNode entry = tool.getEntry((VirtualObjectNode) alias, fieldIndex);
-                if (stamp.isCompatible(entry.stamp())) {
+                if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
                     tool.replaceWith(entry);
                 } else {
-                    assert stamp().getStackKind() == JavaKind.Int && (entry.stamp().getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
+                    assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
                                     entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.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/java/LoadIndexedNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
@@ -92,7 +93,7 @@
 
     private static JavaKind determinePreciseArrayElementType(ValueNode array, JavaKind kind) {
         if (kind == JavaKind.Byte) {
-            ResolvedJavaType javaType = ((ObjectStamp) array.stamp()).type();
+            ResolvedJavaType javaType = ((ObjectStamp) array.stamp(NodeView.DEFAULT)).type();
             if (javaType != null && javaType.isArray() && javaType.getComponentType() != null && javaType.getComponentType().getJavaKind() == JavaKind.Boolean) {
                 return JavaKind.Boolean;
             }
@@ -114,10 +115,10 @@
             int idx = indexValue.isConstant() ? indexValue.asJavaConstant().asInt() : -1;
             if (idx >= 0 && idx < virtual.entryCount()) {
                 ValueNode entry = tool.getEntry(virtual, idx);
-                if (stamp.isCompatible(entry.stamp())) {
+                if (stamp.isCompatible(entry.stamp(NodeView.DEFAULT))) {
                     tool.replaceWith(entry);
                 } else {
-                    assert stamp().getStackKind() == JavaKind.Int && (entry.stamp().getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
+                    assert stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Int && (entry.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Long || entry.getStackKind() == JavaKind.Double ||
                                     entry.getStackKind() == JavaKind.Illegal) : "Can only allow different stack kind two slot marker writes on one stot fields.";
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LogicCompareAndSwapNode.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/java/LogicCompareAndSwapNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 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.NodeLIRBuilderTool;
@@ -58,11 +59,11 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
+        assert getNewValue().stamp(NodeView.DEFAULT).isCompatible(getExpectedValue().stamp(NodeView.DEFAULT));
         assert !this.canDeoptimize();
         LIRGeneratorTool tool = gen.getLIRGeneratorTool();
 
-        LIRKind resultKind = tool.getLIRKind(stamp());
+        LIRKind resultKind = tool.getLIRKind(stamp(NodeView.DEFAULT));
         Value trueResult = tool.emitConstant(resultKind, JavaConstant.TRUE);
         Value falseResult = tool.emitConstant(resultKind, JavaConstant.FALSE);
         Value result = tool.emitLogicCompareAndSwap(gen.operand(getAddress()), gen.operand(getExpectedValue()), gen.operand(getNewValue()), trueResult, falseResult);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoweredAtomicReadAndWriteNode.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/java/LoweredAtomicReadAndWriteNode.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.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.memory.FixedAccessNode;
@@ -55,7 +56,7 @@
     @OptionalInput(State) FrameState stateAfter;
 
     public LoweredAtomicReadAndWriteNode(AddressNode address, LocationIdentity location, ValueNode newValue, BarrierType barrierType) {
-        super(TYPE, address, location, newValue.stamp().unrestricted(), barrierType);
+        super(TYPE, address, location, newValue.stamp(NodeView.DEFAULT).unrestricted(), barrierType);
         this.newValue = newValue;
     }
 
@@ -93,6 +94,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.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/java/MethodCallTargetNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -132,7 +133,7 @@
             return targetMethod;
         }
 
-        return devirtualizeCall(invokeKind, targetMethod, contextType, receiver.graph().getAssumptions(), receiver.stamp());
+        return devirtualizeCall(invokeKind, targetMethod, contextType, receiver.graph().getAssumptions(), receiver.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaMethod devirtualizeCall(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ResolvedJavaType contextType, Assumptions assumptions, Stamp receiverStamp) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewArrayNode.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/java/NewArrayNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.spi.VirtualizableAllocation;
@@ -119,7 +120,8 @@
     @Override
     public void simplify(SimplifierTool tool) {
         if (hasNoUsages()) {
-            Stamp lengthStamp = length().stamp();
+            NodeView view = NodeView.from(tool);
+            Stamp lengthStamp = length().stamp(view);
             if (lengthStamp instanceof IntegerStamp) {
                 IntegerStamp lengthIntegerStamp = (IntegerStamp) lengthStamp;
                 if (lengthIntegerStamp.isPositive()) {
@@ -130,7 +132,7 @@
             // Should be areFrameStatesAtSideEffects but currently SVM will complain about
             // RuntimeConstraint
             if (graph().getGuardsStage().allowsFloatingGuards()) {
-                LogicNode lengthNegativeCondition = CompareNode.createCompareNode(graph(), Condition.LT, length(), ConstantNode.forInt(0, graph()), tool.getConstantReflection());
+                LogicNode lengthNegativeCondition = CompareNode.createCompareNode(graph(), Condition.LT, length(), ConstantNode.forInt(0, graph()), tool.getConstantReflection(), view);
                 // we do not have a non-deopting path for that at the moment so action=None.
                 FixedGuardNode guard = graph().add(new FixedGuardNode(lengthNegativeCondition, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.None, true));
                 graph().replaceFixedWithFixed(this, guard);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RawMonitorEnterNode.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/java/RawMonitorEnterNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.IterableNodeType;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.MonitorEnter;
 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@@ -56,7 +57,7 @@
 
     public RawMonitorEnterNode(ValueNode object, ValueNode hub, MonitorIdNode monitorId) {
         super(TYPE, object, monitorId);
-        assert ((ObjectStamp) object.stamp()).nonNull();
+        assert ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
         this.hub = hub;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/RegisterFinalizerNode.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/java/RegisterFinalizerNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.AbstractStateSplit;
 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;
@@ -87,7 +88,7 @@
      * that must be registered with the runtime upon object initialization.
      */
     public static boolean mayHaveFinalizer(ValueNode object, Assumptions assumptions) {
-        ObjectStamp objectStamp = (ObjectStamp) object.stamp();
+        ObjectStamp objectStamp = (ObjectStamp) object.stamp(NodeView.DEFAULT);
         if (objectStamp.isExactType()) {
             return objectStamp.type().hasFinalizer();
         } else if (objectStamp.type() != null) {
@@ -102,7 +103,8 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (!(forValue.stamp() instanceof ObjectStamp)) {
+        NodeView view = NodeView.from(tool);
+        if (!(forValue.stamp(view) instanceof ObjectStamp)) {
             return this;
         }
         if (!mayHaveFinalizer(forValue, graph().getAssumptions())) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/TypeSwitchNode.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/java/TypeSwitchNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 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.extended.LoadHubNode;
 import org.graalvm.compiler.nodes.extended.SwitchNode;
@@ -64,7 +65,7 @@
         assert successors.length <= keys.length + 1;
         assert keySuccessors.length == keyProbabilities.length;
         this.keys = keys;
-        assert value.stamp() instanceof AbstractPointerStamp;
+        assert value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
         assert assertKeys();
 
         hubs = new Constant[keys.length];
@@ -123,6 +124,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        NodeView view = NodeView.from(tool);
         if (value() instanceof ConstantNode) {
             Constant constant = value().asConstant();
 
@@ -139,8 +141,8 @@
             }
             killOtherSuccessors(tool, survivingEdge);
         }
-        if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp() instanceof ObjectStamp) {
-            ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp();
+        if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp(view) instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(view);
             if (objectStamp.type() != null) {
                 int validKeys = 0;
                 for (int i = 0; i < keyCount(); i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndSwapNode.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/java/UnsafeCompareAndSwapNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+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;
@@ -57,7 +58,7 @@
 
     public UnsafeCompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, JavaKind valueKind, LocationIdentity locationIdentity) {
         super(TYPE, StampFactory.forKind(JavaKind.Boolean.getStackKind()));
-        assert expected.stamp().isCompatible(newValue.stamp());
+        assert expected.stamp(NodeView.DEFAULT).isCompatible(newValue.stamp(NodeView.DEFAULT));
         this.object = object;
         this.offset = offset;
         this.expected = expected;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ValueCompareAndSwapNode.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/java/ValueCompareAndSwapNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.NodeClass;
 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.NodeLIRBuilderTool;
@@ -46,12 +47,12 @@
     }
 
     public ValueCompareAndSwapNode(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location, BarrierType barrierType) {
-        super(TYPE, address, location, expectedValue, newValue, barrierType, expectedValue.stamp().meet(newValue.stamp()).unrestricted());
+        super(TYPE, address, location, expectedValue, newValue, barrierType, expectedValue.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)).unrestricted());
     }
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
+        assert getNewValue().stamp(NodeView.DEFAULT).isCompatible(getExpectedValue().stamp(NodeView.DEFAULT));
         LIRGeneratorTool tool = gen.getLIRGeneratorTool();
         assert !this.canDeoptimize();
         gen.setResult(this, tool.emitValueCompareAndSwap(gen.operand(getAddress()), gen.operand(getExpectedValue()), gen.operand(getNewValue())));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/Access.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/memory/Access.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,8 @@
 
     AddressNode getAddress();
 
+    void setAddress(AddressNode address);
+
     LocationIdentity getLocationIdentity();
 
     boolean canNullCheck();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FixedAccessNode.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/memory/FixedAccessNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -54,6 +54,7 @@
         return address;
     }
 
+    @Override
     public void setAddress(AddressNode address) {
         updateUsages(this.address, address);
         this.address = address;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingAccessNode.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/memory/FloatingAccessNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -59,6 +59,12 @@
     }
 
     @Override
+    public void setAddress(AddressNode address) {
+        updateUsages(this.address, address);
+        this.address = address;
+    }
+
+    @Override
     public LocationIdentity getLocationIdentity() {
         return location;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatingReadNode.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/memory/FloatingReadNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.ValuePhiNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
@@ -65,8 +66,8 @@
         this.lastLocationAccess = lastLocationAccess;
 
         // The input to floating reads must be always non-null or have at least a guard.
-        assert guard != null || !(address.getBase().stamp() instanceof ObjectStamp) || address.getBase() instanceof ValuePhiNode ||
-                        ((ObjectStamp) address.getBase().stamp()).nonNull() : address.getBase();
+        assert guard != null || !(address.getBase().stamp(NodeView.DEFAULT) instanceof ObjectStamp) || address.getBase() instanceof ValuePhiNode ||
+                        ((ObjectStamp) address.getBase().stamp(NodeView.DEFAULT)).nonNull() : address.getBase();
     }
 
     @Override
@@ -82,7 +83,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitLoad(readKind, gen.operand(address), null));
     }
 
@@ -106,7 +107,7 @@
     @Override
     public FixedAccessNode asFixedNode() {
         try (DebugCloseable position = withNodeSourcePosition()) {
-            ReadNode result = graph().add(new ReadNode(getAddress(), getLocationIdentity(), stamp(), getBarrierType()));
+            ReadNode result = graph().add(new ReadNode(getAddress(), getLocationIdentity(), stamp(NodeView.DEFAULT), getBarrierType()));
             result.setGuard(getGuard());
             return result;
         }
@@ -121,6 +122,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.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/memory/ReadNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.CanonicalizableLocation;
 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.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
@@ -94,7 +95,7 @@
     @Override
     public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) {
         try (DebugCloseable position = withNodeSourcePosition()) {
-            return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(), getGuard(), getBarrierType()));
+            return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(NodeView.DEFAULT), getGuard(), getBarrierType()));
         }
     }
 
@@ -104,6 +105,7 @@
     }
 
     public static ValueNode canonicalizeRead(ValueNode read, AddressNode address, LocationIdentity locationIdentity, CanonicalizerTool tool) {
+        NodeView view = NodeView.from(tool);
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (tool.canonicalizeReads() && address instanceof OffsetAddressNode) {
             OffsetAddressNode objAddress = (OffsetAddressNode) address;
@@ -112,10 +114,10 @@
                 long displacement = objAddress.getOffset().asJavaConstant().asLong();
                 int stableDimension = ((ConstantNode) object).getStableDimension();
                 if (locationIdentity.isImmutable() || stableDimension > 0) {
-                    Constant constant = read.stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
+                    Constant constant = read.stamp(view).readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
                     boolean isDefaultStable = locationIdentity.isImmutable() || ((ConstantNode) object).isDefaultStable();
                     if (constant != null && (isDefaultStable || !constant.isDefaultForKind())) {
-                        return ConstantNode.forConstant(read.stamp(), constant, Math.max(stableDimension - 1, 0), isDefaultStable, metaAccess);
+                        return ConstantNode.forConstant(read.stamp(view), constant, Math.max(stableDimension - 1, 0), isDefaultStable, metaAccess);
                     }
                 }
             }
@@ -128,7 +130,7 @@
             if (locationIdentity instanceof CanonicalizableLocation) {
                 CanonicalizableLocation canonicalize = (CanonicalizableLocation) locationIdentity;
                 ValueNode result = canonicalize.canonicalizeRead(read, address, object, tool);
-                assert result != null && result.stamp().isCompatible(read.stamp());
+                assert result != null && result.stamp(view).isCompatible(read.stamp(view));
                 return result;
             }
 
@@ -148,6 +150,6 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/WriteNode.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/memory/WriteNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.NodeLIRBuilderTool;
@@ -52,7 +53,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp());
+        LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp(NodeView.DEFAULT));
         gen.getLIRGeneratorTool().getArithmetic().emitStore(writeKind, gen.operand(address), gen.operand(value()), gen.state(this));
     }
 
@@ -63,7 +64,7 @@
 
     @Override
     public Stamp getAccessStamp() {
-        return value().stamp();
+        return value().stamp(NodeView.DEFAULT);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.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/memory/address/OffsetAddressNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 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.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -31,6 +32,8 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.InputType;
 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.AddNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
@@ -54,8 +57,12 @@
         this.base = base;
         this.offset = offset;
 
-        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64) &&
-                        offset != null && IntegerStamp.getBits(offset.stamp()) == 64 : "both values must have 64 bits";
+        assert base != null && (base.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp(NodeView.DEFAULT)) == 64) &&
+                        offset != null && IntegerStamp.getBits(offset.stamp(NodeView.DEFAULT)) == 64 : "both values must have 64 bits";
+    }
+
+    public static OffsetAddressNode create(ValueNode base) {
+        return new OffsetAddressNode(base, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(base.stamp(NodeView.DEFAULT)), 0));
     }
 
     @Override
@@ -66,7 +73,7 @@
     public void setBase(ValueNode base) {
         updateUsages(this.base, base);
         this.base = base;
-        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64);
+        assert base != null && (base.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp(NodeView.DEFAULT)) == 64);
     }
 
     public ValueNode getOffset() {
@@ -76,18 +83,16 @@
     public void setOffset(ValueNode offset) {
         updateUsages(this.offset, offset);
         this.offset = offset;
-        assert offset != null && IntegerStamp.getBits(offset.stamp()) == 64;
+        assert offset != null && IntegerStamp.getBits(offset.stamp(NodeView.DEFAULT)) == 64;
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (base instanceof RawAddressNode) {
-            // The RawAddressNode is redundant, just directly use its input as base.
-            return new OffsetAddressNode(((RawAddressNode) base).getAddress(), offset);
-        } else if (base instanceof OffsetAddressNode) {
+        if (base instanceof OffsetAddressNode) {
+            NodeView view = NodeView.from(tool);
             // Rewrite (&base[offset1])[offset2] to base[offset1 + offset2].
             OffsetAddressNode b = (OffsetAddressNode) base;
-            return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset()));
+            return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset(), view));
         } else if (base instanceof AddNode) {
             AddNode add = (AddNode) base;
             if (add.getY().isConstant()) {
@@ -102,7 +107,7 @@
 
     @Override
     public long getMaxConstantDisplacement() {
-        Stamp curStamp = offset.stamp();
+        Stamp curStamp = offset.stamp(NodeView.DEFAULT);
         if (curStamp instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) curStamp;
             if (integerStamp.lowerBound() >= 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/RawAddressNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, 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.memory.address;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-
-/**
- * Convert a word-sized integer to a raw address.
- */
-@NodeInfo(allowedUsageTypes = InputType.Association)
-public class RawAddressNode extends AddressNode {
-    public static final NodeClass<RawAddressNode> TYPE = NodeClass.create(RawAddressNode.class);
-
-    @Input ValueNode address;
-
-    public RawAddressNode(ValueNode address) {
-        super(TYPE);
-        this.address = address;
-    }
-
-    public ValueNode getAddress() {
-        return address;
-    }
-
-    public void setAddress(ValueNode address) {
-        updateUsages(this.address, address);
-        this.address = address;
-    }
-
-    @Override
-    public ValueNode getBase() {
-        return address;
-    }
-
-    @Override
-    public long getMaxConstantDisplacement() {
-        return 0;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return null;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/type/StampTool.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/type/StampTool.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.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -61,9 +62,9 @@
             ValueNode nextValue = iterator.next();
             if (nextValue != selfValue) {
                 if (stamp == null) {
-                    stamp = nextValue.stamp();
+                    stamp = nextValue.stamp(NodeView.DEFAULT);
                 } else {
-                    stamp = stamp.meet(nextValue.stamp());
+                    stamp = stamp.meet(nextValue.stamp(NodeView.DEFAULT));
                 }
             }
         }
@@ -132,7 +133,7 @@
      * @return true if this node represents a legal object value which is known to be always null
      */
     public static boolean isPointerAlwaysNull(ValueNode node) {
-        return isPointerAlwaysNull(node.stamp());
+        return isPointerAlwaysNull(node.stamp(NodeView.DEFAULT));
     }
 
     /**
@@ -158,7 +159,7 @@
      * @return true if this node represents a legal object value which is known to never be null
      */
     public static boolean isPointerNonNull(ValueNode node) {
-        return isPointerNonNull(node.stamp());
+        return isPointerNonNull(node.stamp(NodeView.DEFAULT));
     }
 
     /**
@@ -184,11 +185,11 @@
      * @return the Java type this value has if it is a legal Object type, null otherwise
      */
     public static TypeReference typeReferenceOrNull(ValueNode node) {
-        return typeReferenceOrNull(node.stamp());
+        return typeReferenceOrNull(node.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaType typeOrNull(ValueNode node) {
-        return typeOrNull(node.stamp());
+        return typeOrNull(node.stamp(NodeView.DEFAULT));
     }
 
     public static ResolvedJavaType typeOrNull(Stamp stamp) {
@@ -210,7 +211,7 @@
     }
 
     public static ResolvedJavaType typeOrNull(ValueNode node, MetaAccessProvider metaAccess) {
-        return typeOrNull(node.stamp(), metaAccess);
+        return typeOrNull(node.stamp(NodeView.DEFAULT), metaAccess);
     }
 
     /**
@@ -242,7 +243,7 @@
      * @return true if this node represents a legal object value whose Java type is known exactly
      */
     public static boolean isExactType(ValueNode node) {
-        return isExactType(node.stamp());
+        return isExactType(node.stamp(NodeView.DEFAULT));
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.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/util/GraphUtil.java	Fri Dec 01 11:17:45 2017 -0800
@@ -55,6 +55,7 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopEndNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -652,7 +653,7 @@
         ValueNode n = node;
         while (n instanceof PiNode) {
             PiNode piNode = (PiNode) n;
-            ObjectStamp originalStamp = (ObjectStamp) piNode.getOriginalNode().stamp();
+            ObjectStamp originalStamp = (ObjectStamp) piNode.getOriginalNode().stamp(NodeView.DEFAULT);
             if (originalStamp.nonNull()) {
                 n = piNode.getOriginalNode();
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/CommitAllocationNode.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/virtual/CommitAllocationNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -111,7 +112,7 @@
     public void lower(LoweringTool tool) {
         for (int i = 0; i < virtualObjects.size(); i++) {
             if (ensureVirtual.get(i)) {
-                EnsureVirtualizedNode.ensureVirtualFailure(this, virtualObjects.get(i).stamp());
+                EnsureVirtualizedNode.ensureVirtualFailure(this, virtualObjects.get(i).stamp(NodeView.DEFAULT));
             }
         }
         tool.getLowerer().lower(this, tool);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/EnsureVirtualizedNode.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/virtual/EnsureVirtualizedNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.StoreFieldNode;
 import org.graalvm.compiler.nodes.spi.Lowerable;
@@ -76,7 +77,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ensureVirtualFailure(this, object.stamp());
+        ensureVirtualFailure(this, object.stamp(NodeView.DEFAULT));
     }
 
     public static void ensureVirtualFailure(Node location, Stamp stamp) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringByUsePhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,10 +23,10 @@
  */
 package org.graalvm.compiler.phases.common;
 
-import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PrefetchAllocateNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -36,10 +36,11 @@
 import org.graalvm.compiler.nodes.memory.ReadNode;
 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.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.Phase;
 
+import jdk.vm.ci.meta.JavaKind;
+
 /**
  * Created by adinn on 09/05/17.
  */
@@ -66,22 +67,22 @@
             AddressNode lowered;
             if (node instanceof ReadNode) {
                 ReadNode readNode = (ReadNode) node;
-                Stamp stamp = readNode.stamp();
+                Stamp stamp = readNode.stamp(NodeView.DEFAULT);
                 address = readNode.getAddress();
                 lowered = lowering.lower(readNode, stamp, address);
             } else if (node instanceof JavaReadNode) {
                 JavaReadNode javaReadNode = (JavaReadNode) node;
-                Stamp stamp = javaReadNode.stamp();
+                Stamp stamp = javaReadNode.stamp(NodeView.DEFAULT);
                 address = javaReadNode.getAddress();
                 lowered = lowering.lower(javaReadNode, stamp, address);
             } else if (node instanceof FloatingReadNode) {
                 FloatingReadNode floatingReadNode = (FloatingReadNode) node;
-                Stamp stamp = floatingReadNode.stamp();
+                Stamp stamp = floatingReadNode.stamp(NodeView.DEFAULT);
                 address = floatingReadNode.getAddress();
                 lowered = lowering.lower(floatingReadNode, stamp, address);
             } else if (node instanceof AbstractWriteNode) {
                 AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
-                Stamp stamp = abstractWriteNode.value().stamp();
+                Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT);
                 address = abstractWriteNode.getAddress();
                 lowered = lowering.lower(abstractWriteNode, stamp, address);
             } else if (node instanceof PrefetchAllocateNode) {
@@ -108,7 +109,7 @@
         // now replace any remaining unlowered address nodes
         for (Node node : graph.getNodes()) {
             AddressNode lowered;
-            if (node instanceof RawAddressNode || node instanceof OffsetAddressNode) {
+            if (node instanceof OffsetAddressNode) {
                 AddressNode address = (AddressNode) node;
                 lowered = lowering.lower(address);
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/AddressLoweringPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -27,16 +27,12 @@
 import org.graalvm.compiler.nodes.ValueNode;
 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.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.Phase;
 
 public class AddressLoweringPhase extends Phase {
 
     public abstract static class AddressLowering {
-
-        public abstract AddressNode lower(ValueNode address);
-
         public abstract AddressNode lower(ValueNode base, ValueNode offset);
     }
 
@@ -51,10 +47,7 @@
     protected void run(StructuredGraph graph) {
         for (Node node : graph.getNodes()) {
             AddressNode lowered;
-            if (node instanceof RawAddressNode) {
-                RawAddressNode address = (RawAddressNode) node;
-                lowered = lowering.lower(address.getAddress());
-            } else if (node instanceof OffsetAddressNode) {
+            if (node instanceof OffsetAddressNode) {
                 OffsetAddressNode address = (OffsetAddressNode) node;
                 lowered = lowering.lower(address.getBase(), address.getOffset());
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.phases.common;
 
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
@@ -44,6 +45,7 @@
 import org.graalvm.compiler.nodes.ControlSinkNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StartNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -153,6 +155,10 @@
         new Instance(context, workingSet, newNodesMark).apply(graph, dumpGraph);
     }
 
+    public NodeView getNodeView() {
+        return NodeView.DEFAULT;
+    }
+
     private final class Instance extends Phase {
 
         private final Mark newNodesMark;
@@ -260,9 +266,9 @@
             if (node instanceof ValueNode) {
                 ValueNode valueNode = (ValueNode) node;
                 boolean improvedStamp = tryInferStamp(valueNode);
-                Constant constant = valueNode.stamp().asConstant();
+                Constant constant = valueNode.stamp(NodeView.DEFAULT).asConstant();
                 if (constant != null && !(node instanceof ConstantNode)) {
-                    ConstantNode stampConstant = ConstantNode.forConstant(valueNode.stamp(), constant, context.getMetaAccess(), graph);
+                    ConstantNode stampConstant = ConstantNode.forConstant(valueNode.stamp(NodeView.DEFAULT), constant, context.getMetaAccess(), graph);
                     debug.log("Canonicalizer: constant stamp replaces %1s with %1s", valueNode, stampConstant);
                     valueNode.replaceAtUsages(InputType.Value, stampConstant);
                     GraphUtil.tryKillUnused(valueNode);
@@ -442,14 +448,16 @@
             return false;
         }
 
-        private final class Tool implements SimplifierTool {
+        private final class Tool implements SimplifierTool, NodeView {
 
             private final Assumptions assumptions;
             private final OptionValues options;
+            private NodeView nodeView;
 
             Tool(Assumptions assumptions, OptionValues options) {
                 this.assumptions = assumptions;
                 this.options = options;
+                this.nodeView = getNodeView();
             }
 
             @Override
@@ -513,6 +521,11 @@
             public OptionValues getOptions() {
                 return options;
             }
+
+            @Override
+            public Stamp stamp(ValueNode node) {
+                return nodeView.stamp(node);
+            }
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -58,6 +58,7 @@
 import org.graalvm.compiler.nodes.LogicNode;
 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.ProxyNode;
@@ -414,7 +415,7 @@
                     Stamp bestPossibleStamp = null;
                     for (int i = 0; i < phi.valueCount(); ++i) {
                         ValueNode valueAt = phi.valueAt(i);
-                        Stamp curBestStamp = valueAt.stamp();
+                        Stamp curBestStamp = valueAt.stamp(NodeView.DEFAULT);
                         InfoElement infoElement = phiInfoElements.get(merge.forwardEndAt(i));
                         if (infoElement != null) {
                             curBestStamp = curBestStamp.join(infoElement.getStamp());
@@ -427,7 +428,7 @@
                         }
                     }
 
-                    Stamp oldStamp = phi.stamp();
+                    Stamp oldStamp = phi.stamp(NodeView.DEFAULT);
                     if (oldStamp.tryImproveWith(bestPossibleStamp) != null) {
 
                         // Need to be careful to not run into stamp update cycles with the iterative
@@ -460,7 +461,7 @@
                             ValuePhiNode newPhi = graph.addWithoutUnique(new ValuePhiNode(bestPossibleStamp, merge));
                             for (int i = 0; i < phi.valueCount(); ++i) {
                                 ValueNode valueAt = phi.valueAt(i);
-                                if (bestPossibleStamp.meet(valueAt.stamp()).equals(bestPossibleStamp)) {
+                                if (bestPossibleStamp.meet(valueAt.stamp(NodeView.DEFAULT)).equals(bestPossibleStamp)) {
                                     // Pi not required here.
                                 } else {
                                     InfoElement infoElement = phiInfoElements.get(merge.forwardEndAt(i));
@@ -494,7 +495,7 @@
                     InfoElement infoElement = this.getInfoElements(valueAt);
                     while (infoElement != null) {
                         Stamp newStamp = infoElement.getStamp();
-                        if (phi.stamp().tryImproveWith(newStamp) != null) {
+                        if (phi.stamp(NodeView.DEFAULT).tryImproveWith(newStamp) != null) {
                             if (mergeMap == null) {
                                 mergeMap = EconomicMap.create();
                                 mergeMaps.put(merge, mergeMap);
@@ -547,7 +548,7 @@
                              * It's equivalent to or'ing in the mask value since those values are
                              * known to be set.
                              */
-                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
+                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT)).getOr();
                             IntegerStamp newStampX = (IntegerStamp) op.foldStamp(getSafeStamp(andX), getOtherSafeStamp(y));
                             registerNewStamp(andX, newStampX, guard);
                         }
@@ -580,7 +581,7 @@
                 if (y.isConstant()) {
                     InfoElement infoElement = getInfoElements(x);
                     while (infoElement != null) {
-                        Stamp result = binary.foldStamp(infoElement.stamp, y.stamp());
+                        Stamp result = binary.foldStamp(infoElement.stamp, y.stamp(NodeView.DEFAULT));
                         if (result != null) {
                             return Pair.create(infoElement, result);
                         }
@@ -597,7 +598,7 @@
          * registered info elements is in the same chain of pi nodes.
          */
         private static Stamp getSafeStamp(ValueNode x) {
-            return x.stamp();
+            return x.stamp(NodeView.DEFAULT);
         }
 
         /**
@@ -610,9 +611,9 @@
          */
         private static Stamp getOtherSafeStamp(ValueNode x) {
             if (x.isConstant()) {
-                return x.stamp();
+                return x.stamp(NodeView.DEFAULT);
             }
-            return x.stamp().unrestricted();
+            return x.stamp(NodeView.DEFAULT).unrestricted();
         }
 
         /**
@@ -777,7 +778,7 @@
                 ValueNode y = binaryOpLogicNode.getY();
                 infoElement = getInfoElements(x);
                 while (infoElement != null) {
-                    TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp());
+                    TriState result = binaryOpLogicNode.tryFold(infoElement.getStamp(), y.stamp(NodeView.DEFAULT));
                     if (result.isKnown()) {
                         return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), infoElement.getStamp(), rewireGuardFunction);
                     }
@@ -787,7 +788,7 @@
                 if (y.isConstant()) {
                     Pair<InfoElement, Stamp> foldResult = recursiveFoldStampFromInfo(x);
                     if (foldResult != null) {
-                        TriState result = binaryOpLogicNode.tryFold(foldResult.getRight(), y.stamp());
+                        TriState result = binaryOpLogicNode.tryFold(foldResult.getRight(), y.stamp(NodeView.DEFAULT));
                         if (result.isKnown()) {
                             return rewireGuards(foldResult.getLeft().getGuard(), result.toBoolean(), foldResult.getLeft().getProxifiedInput(), foldResult.getRight(), rewireGuardFunction);
                         }
@@ -795,7 +796,7 @@
                 } else {
                     infoElement = getInfoElements(y);
                     while (infoElement != null) {
-                        TriState result = binaryOpLogicNode.tryFold(x.stamp(), infoElement.getStamp());
+                        TriState result = binaryOpLogicNode.tryFold(x.stamp(NodeView.DEFAULT), infoElement.getStamp());
                         if (result.isKnown()) {
                             return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), infoElement.getStamp(), rewireGuardFunction);
                         }
@@ -815,8 +816,8 @@
                     if (binary.getY().isConstant()) {
                         infoElement = getInfoElements(binary.getX());
                         while (infoElement != null) {
-                            Stamp newStampX = binary.foldStamp(infoElement.getStamp(), binary.getY().stamp());
-                            TriState result = binaryOpLogicNode.tryFold(newStampX, y.stamp());
+                            Stamp newStampX = binary.foldStamp(infoElement.getStamp(), binary.getY().stamp(NodeView.DEFAULT));
+                            TriState result = binaryOpLogicNode.tryFold(newStampX, y.stamp(NodeView.DEFAULT));
                             if (result.isKnown()) {
                                 return rewireGuards(infoElement.getGuard(), result.toBoolean(), infoElement.getProxifiedInput(), newStampX, rewireGuardFunction);
                             }
@@ -834,7 +835,7 @@
                              * It's equivalent to or'ing in the mask value since those values are
                              * known to be set.
                              */
-                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp()).getOr();
+                            BinaryOp<Or> op = ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT)).getOr();
                             IntegerStamp newStampX = (IntegerStamp) op.foldStamp(getSafeStamp(and.getX()), getOtherSafeStamp(y));
                             if (foldPendingTest(thisGuard, and.getX(), newStampX, rewireGuardFunction)) {
                                 return true;
@@ -899,7 +900,7 @@
                 do {
                     counterStampsRegistered.increment(debug);
                     debug.log("\t Saving stamp for node %s stamp %s guarded by %s", value, stamp, guard);
-                    assert value instanceof LogicNode || stamp.isCompatible(value.stamp()) : stamp + " vs. " + value.stamp() + " (" + value + ")";
+                    assert value instanceof LogicNode || stamp.isCompatible(value.stamp(NodeView.DEFAULT)) : stamp + " vs. " + value.stamp(NodeView.DEFAULT) + " (" + value + ")";
                     map.setAndGrow(value, new InfoElement(stamp, guard, proxiedValue, map.getAndGrow(value)));
                     undoOperations.push(value);
                     if (value instanceof StampInverter) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ExpandLogicPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ShortCircuitOrNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -68,15 +69,15 @@
         StructuredGraph graph = normalize.graph();
         ValueNode x = normalize.getX();
         ValueNode y = normalize.getY();
-        if (x.stamp() instanceof FloatStamp) {
-            equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y));
-            lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess()));
+        if (x.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
+            equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y, NodeView.DEFAULT));
+            lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess(), NodeView.DEFAULT));
         } else {
-            equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y));
-            lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y));
+            equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y, NodeView.DEFAULT));
+            lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y, NodeView.DEFAULT));
         }
 
-        Stamp stamp = normalize.stamp();
+        Stamp stamp = normalize.stamp(NodeView.DEFAULT);
         ConditionalNode equalValue = graph.unique(
                         new ConditionalNode(equalComp, ConstantNode.forIntegerStamp(stamp, 0, graph), ConstantNode.forIntegerStamp(stamp, 1, graph)));
         ConditionalNode value = graph.unique(new ConditionalNode(lessComp, ConstantNode.forIntegerStamp(stamp, -1, graph), equalValue));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -115,7 +116,7 @@
                 replaceCurrent(fixedAccess);
             } else if (node instanceof PiNode) {
                 PiNode piNode = (PiNode) node;
-                if (piNode.stamp().isCompatible(piNode.getOriginalNode().stamp())) {
+                if (piNode.stamp(NodeView.DEFAULT).isCompatible(piNode.getOriginalNode().stamp(NodeView.DEFAULT))) {
                     // Pi nodes are no longer necessary at this point.
                     piNode.replaceAndDelete(piNode.getOriginalNode());
                 }
@@ -178,7 +179,7 @@
                                 }
                                 counterConstantInputReplacements.increment(node.getDebug());
                                 ConstantNode stampConstant = ConstantNode.forConstant(bestStamp, constant, metaAccess, graph);
-                                assert stampConstant.stamp().isCompatible(valueNode.stamp());
+                                assert stampConstant.stamp(NodeView.DEFAULT).isCompatible(valueNode.stamp(NodeView.DEFAULT));
                                 replaceInput(p, node, stampConstant);
                                 replacements++;
                             }
@@ -258,7 +259,7 @@
                                 bestStamp = bestStamp.meet(currentEndMap.get(phi));
                             }
 
-                            if (!bestStamp.equals(phi.stamp())) {
+                            if (!bestStamp.equals(phi.stamp(NodeView.DEFAULT))) {
                                 endMap.put(phi, bestStamp);
                             }
                         }
@@ -293,7 +294,7 @@
                                     bestStamp = bestStamp.meet(otherEndsStamp);
                                 }
 
-                                if (nodeWithNewStamp.stamp().tryImproveWith(bestStamp) == null) {
+                                if (nodeWithNewStamp.stamp(NodeView.DEFAULT).tryImproveWith(bestStamp) == null) {
                                     // No point in registering the stamp.
                                 } else {
                                     endMap.put(nodeWithNewStamp, bestStamp);
@@ -462,7 +463,7 @@
             ValueNode originalNode = value;
             StampElement currentStamp = stampMap.getAndGrow(originalNode);
             if (currentStamp == null) {
-                return value.stamp();
+                return value.stamp(NodeView.DEFAULT);
             }
             return currentStamp.getStamp();
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NonNullParametersPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NonNullParametersPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -25,6 +25,7 @@
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.phases.Phase;
@@ -39,8 +40,8 @@
     protected void run(StructuredGraph graph) {
         Stamp nonNull = StampFactory.objectNonNull();
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
-            if (param.stamp() instanceof ObjectStamp) {
-                ObjectStamp paramStamp = (ObjectStamp) param.stamp();
+            if (param.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                ObjectStamp paramStamp = (ObjectStamp) param.stamp(NodeView.DEFAULT);
                 param.setStamp(paramStamp.join(nonNull));
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Fri Dec 01 11:17:45 2017 -0800
@@ -160,7 +160,7 @@
             return 10;
         } else if (node instanceof Access) {
             return 2;
-        } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
+        } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof NotNode) {
             return 1;
         } else if (node instanceof IntegerDivRemNode || node instanceof FloatDivNode || node instanceof RemNode) {
             return 10;
@@ -168,7 +168,7 @@
             return 3;
         } else if (node instanceof Invoke) {
             return 5;
-        } else if (node instanceof IfNode || node instanceof SafepointNode) {
+        } else if (node instanceof IfNode || node instanceof SafepointNode || node instanceof BinaryNode) {
             return 1;
         } else if (node instanceof SwitchNode) {
             return node.successors().count();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Fri Dec 01 11:17:45 2017 -0800
@@ -69,6 +69,7 @@
 import org.graalvm.compiler.nodes.KillingBeginNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
@@ -827,7 +828,7 @@
         if (newReceiver.getStackKind() == JavaKind.Object) {
 
             if (invoke.getInvokeKind() == InvokeKind.Special) {
-                Stamp paramStamp = newReceiver.stamp();
+                Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
                 Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
                 if (!stamp.equals(paramStamp)) {
                     // The verifier and previous optimizations guarantee unconditionally that the
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -191,7 +192,7 @@
 
         PhiNode returnValuePhi = null;
         if (invoke.asNode().getStackKind() != JavaKind.Void) {
-            returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp().unrestricted(), returnMerge));
+            returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
         }
 
         AbstractMergeNode exceptionMerge = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/TypeGuardInlineInfo.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.Invoke;
 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.calc.CompareNode;
@@ -111,9 +112,9 @@
     private void createGuard(StructuredGraph graph, Providers providers) {
         ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
         LoadHubNode receiverHub = graph.unique(new LoadHubNode(providers.getStampProvider(), nonNullReceiver));
-        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
+        ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(NodeView.DEFAULT), providers.getConstantReflection().asObjectHub(type), providers.getMetaAccess(), graph);
 
-        LogicNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub, providers.getConstantReflection());
+        LogicNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub, providers.getConstantReflection(), NodeView.DEFAULT);
         FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
         assert invoke.predecessor() != null;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@@ -120,8 +121,8 @@
     }
 
     private static Stamp improvedStamp(ValueNode arg, ParameterNode param) {
-        Stamp joinedStamp = param.stamp().join(arg.stamp());
-        if (joinedStamp == null || joinedStamp.equals(param.stamp())) {
+        Stamp joinedStamp = param.stamp(NodeView.DEFAULT).join(arg.stamp(NodeView.DEFAULT));
+        if (joinedStamp == null || joinedStamp.equals(param.stamp(NodeView.DEFAULT))) {
             return null;
         }
         return joinedStamp;
@@ -162,7 +163,7 @@
                     parameterUsages = trackParameterUsages(param, parameterUsages);
                     // collect param usages before replacing the param
                     param.replaceAtUsagesAndDelete(graph.unique(
-                                    ConstantNode.forConstant(arg.stamp(), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
+                                    ConstantNode.forConstant(arg.stamp(NodeView.DEFAULT), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
                     // param-node gone, leaving a gap in the sequence given by param.index()
                 } else {
                     Stamp impro = improvedStamp(arg, param);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Fri Dec 01 11:17:45 2017 -0800
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.CallTargetNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -192,10 +193,10 @@
         assert callTarget.invokeKind().isIndirect();
 
         ResolvedJavaType holder = targetMethod.getDeclaringClass();
-        if (!(callTarget.receiver().stamp() instanceof ObjectStamp)) {
+        if (!(callTarget.receiver().stamp(NodeView.DEFAULT) instanceof ObjectStamp)) {
             return null;
         }
-        ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp();
+        ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp(NodeView.DEFAULT);
         if (receiverStamp.alwaysNull()) {
             // Don't inline if receiver is known to be null
             return null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/InferStamps.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/graph/InferStamps.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -50,9 +51,9 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
-                if (node.stamp() instanceof ObjectStamp) {
-                    assert node.stamp().hasValues() : "We assume all Phi and Proxy stamps are legal before the analysis";
-                    node.setStamp(node.stamp().empty());
+                if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
+                    assert node.stamp(NodeView.DEFAULT).hasValues() : "We assume all Phi and Proxy stamps are legal before the analysis";
+                    node.setStamp(node.stamp(NodeView.DEFAULT).empty());
                 }
             }
         }
@@ -71,7 +72,7 @@
             for (Node n : graph.getNodes()) {
                 if (n instanceof ValueNode) {
                     ValueNode node = (ValueNode) n;
-                    if (node.stamp() instanceof ObjectStamp) {
+                    if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
                         stampChanged |= node.inferStamp();
                     }
                 }
@@ -90,7 +91,8 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
-                assert node.stamp().hasValues() : "Stamp is empty after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
+                assert node.stamp(
+                                NodeView.DEFAULT).hasValues() : "Stamp is empty after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
             }
         }
         return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/ValueMergeUtil.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.nodes.ControlSinkNode;
 import org.graalvm.compiler.nodes.EndNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.UnwindNode;
@@ -52,7 +53,7 @@
                     singleResult = result;
                 } else if (phiResult == null) {
                     /* Found a second result value, so create phi node. */
-                    phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp().unrestricted(), merge));
+                    phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp(NodeView.DEFAULT).unrestricted(), merge));
                     for (int i = 0; i < merge.forwardEndCount(); i++) {
                         phiResult.addInput(singleResult);
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyDebugUsage.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,7 @@
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodes.CallTargetNode;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
@@ -234,7 +235,7 @@
 
     protected void verifyDumpObjectParameter(StructuredGraph callerGraph, MethodCallTargetNode debugCallTarget, ValueNode arg, ResolvedJavaMethod verifiedCallee, Integer dumpLevel)
                     throws org.graalvm.compiler.phases.VerifyPhase.VerificationError {
-        ResolvedJavaType argType = ((ObjectStamp) arg.stamp()).type();
+        ResolvedJavaType argType = ((ObjectStamp) arg.stamp(NodeView.DEFAULT)).type();
         if (metaAccess.lookupJavaType(Graph.class).isAssignableFrom(argType)) {
             verifyStructuredGraphDumping(callerGraph, debugCallTarget, verifiedCallee, dumpLevel);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyUsageWithEquals.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyUsageWithEquals.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -80,7 +81,7 @@
      * Determines whether the type of {@code node} is assignable to the {@link #restrictedClass}.
      */
     private boolean isAssignableToRestrictedType(ValueNode node, MetaAccessProvider metaAccess) {
-        if (node.stamp() instanceof ObjectStamp) {
+        if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
             ResolvedJavaType restrictedType = metaAccess.lookupJavaType(restrictedClass);
             ResolvedJavaType nodeType = StampTool.typeOrNull(node);
             if (nodeType == null && node instanceof LoadFieldNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyVirtualizableUsage.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyVirtualizableUsage.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeInputList;
 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.java.MethodCallTargetNode;
@@ -81,7 +82,7 @@
         int i = 0;
         for (Node arg : arguments) {
             if (i >= startIdx) {
-                Stamp argStamp = ((ValueNode) arg).stamp();
+                Stamp argStamp = ((ValueNode) arg).stamp(NodeView.DEFAULT);
                 if (argStamp instanceof ObjectStamp) {
                     ObjectStamp objectStamp = (ObjectStamp) argStamp;
                     ResolvedJavaType argStampType = objectStamp.type();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Fri Dec 01 11:17:45 2017 -0800
@@ -92,7 +92,7 @@
 
     @Override
     public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) throws IOException {
-        output.beginGroup(new GraphInfo(debug, null), name, shortName, method, bci, properties);
+        output.beginGroup(new GraphInfo(debug, null), name, shortName, method, bci, DebugContext.addVersionProperties(properties));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountLeadingZerosNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -48,7 +49,7 @@
     public static final NodeClass<AArch64CountLeadingZerosNode> TYPE = NodeClass.create(AArch64CountLeadingZerosNode.class);
 
     public AArch64CountLeadingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
     }
 
     @Override
@@ -57,7 +58,7 @@
     }
 
     private static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         assert theValue.getStackKind() == JavaKind.Int || theValue.getStackKind() == JavaKind.Long;
         return StampTool.stampForLeadingZeros((IntegerStamp) newStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64CountTrailingZerosNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AArch64CountTrailingZerosNode> TYPE = NodeClass.create(AArch64CountTrailingZerosNode.class);
 
     public AArch64CountTrailingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode value) {
-        assert newStamp.isCompatible(value.stamp());
+        assert newStamp.isCompatible(value.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         return StampTool.stampForTrailingZeros(valueStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
 import org.graalvm.compiler.graph.NodeClass;
 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.RemNode;
@@ -63,7 +64,7 @@
     }
 
     public void lower(RemNode node, LoweringTool tool) {
-        JavaKind kind = node.stamp().getStackKind();
+        JavaKind kind = node.stamp(NodeView.DEFAULT).getStackKind();
         assert kind == JavaKind.Float || kind == JavaKind.Double;
         if (node instanceof SafeNode) {
             // We already introduced the necessary checks, nothing to do.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.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.DeoptimizeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FixedBinaryNode;
@@ -84,7 +85,7 @@
     }
 
     public void lower(FixedBinaryNode node, LoweringTool tool) {
-        JavaKind kind = node.stamp().getStackKind();
+        JavaKind kind = node.stamp(NodeView.DEFAULT).getStackKind();
         assert kind == JavaKind.Int || kind == JavaKind.Long;
         SnippetTemplate.SnippetInfo snippet;
         if (node instanceof SafeNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64ReadNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SignExtendNode;
@@ -66,7 +67,7 @@
         AArch64LIRGenerator lirgen = (AArch64LIRGenerator) gen.getLIRGeneratorTool();
         AArch64ArithmeticLIRGenerator arithgen = (AArch64ArithmeticLIRGenerator) lirgen.getArithmetic();
         AArch64Kind readKind = (AArch64Kind) lirgen.getLIRKind(accessStamp).getPlatformKind();
-        int resultBits = ((IntegerStamp) stamp()).getBits();
+        int resultBits = ((IntegerStamp) stamp(NodeView.DEFAULT)).getBits();
         gen.setResult(this, arithgen.emitExtendMemory(isSigned, readKind, resultBits, (AArch64AddressValue) gen.operand(getAddress()), gen.state(this)));
     }
 
@@ -86,7 +87,7 @@
 
         AddressNode address = readNode.getAddress();
         LocationIdentity location = readNode.getLocationIdentity();
-        Stamp stamp = usage.stamp();
+        Stamp stamp = usage.stamp(NodeView.DEFAULT);
         GuardingNode guard = readNode.getGuard();
         BarrierType barrierType = readNode.getBarrierType();
         boolean nullCheck = readNode.getNullCheck();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountLeadingZerosNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AMD64CountLeadingZerosNode> TYPE = NodeClass.create(AMD64CountLeadingZerosNode.class);
 
     public AMD64CountLeadingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     private static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         assert theValue.getStackKind() == JavaKind.Int || theValue.getStackKind() == JavaKind.Long;
         return StampTool.stampForLeadingZeros((IntegerStamp) newStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64CountTrailingZerosNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -50,7 +51,7 @@
     public static final NodeClass<AMD64CountTrailingZerosNode> TYPE = NodeClass.create(AMD64CountTrailingZerosNode.class);
 
     public AMD64CountTrailingZerosNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -60,7 +61,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode value) {
-        assert newStamp.isCompatible(value.stamp());
+        assert newStamp.isCompatible(value.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         return StampTool.stampForTrailingZeros(valueStamp);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64RoundNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64RoundNode.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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -52,7 +53,7 @@
     private final RoundingMode mode;
 
     public AMD64RoundNode(ValueNode value, RoundingMode mode) {
-        super(TYPE, roundStamp((FloatStamp) value.stamp(), mode), value);
+        super(TYPE, roundStamp((FloatStamp) value.stamp(NodeView.DEFAULT), mode), value);
         this.mode = mode;
     }
 
@@ -83,7 +84,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         return roundStamp((FloatStamp) newStamp, mode);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/BitOpNodesTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.replacements.test;
 
+import org.graalvm.compiler.nodes.NodeView;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Test;
@@ -83,7 +84,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountIntSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 24), result.stamp(NodeView.DEFAULT));
     }
 
     public static int bitCountIntEmptySnippet(int v) {
@@ -97,7 +98,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountIntEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 24), result.stamp(NodeView.DEFAULT));
     }
 
     @Test
@@ -117,7 +118,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountLongSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 8, 40), result.stamp(NodeView.DEFAULT));
     }
 
     public static int bitCountLongEmptySnippet(long v) {
@@ -131,7 +132,7 @@
         boolean isSparc = arch instanceof SPARC;
         Assume.assumeTrue("Only works on hardware with popcnt at the moment", isAmd64WithPopCount || isSparc);
         ValueNode result = parseAndInline("bitCountLongEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 0, 40), result.stamp(NodeView.DEFAULT));
     }
 
     /*
@@ -155,7 +156,7 @@
     @Test
     public void testScanForwardInt() {
         ValueNode result = parseAndInline("scanForwardIntSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 4, 8), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 4, 8), result.stamp(NodeView.DEFAULT));
     }
 
     public static int scanForwardLongConstantSnippet() {
@@ -175,7 +176,7 @@
     @Test
     public void testScanForwardLong() {
         ValueNode result = parseAndInline("scanForwardLongSnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 32), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 32), result.stamp(NodeView.DEFAULT));
     }
 
     public static int scanForwardLongEmptySnippet(long v) {
@@ -187,7 +188,7 @@
     @Test
     public void testScanForwardLongEmpty() {
         ValueNode result = parseAndInline("scanForwardLongEmptySnippet");
-        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp());
+        Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp(NodeView.DEFAULT));
     }
 
     /*
@@ -213,7 +214,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseIntSnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 16, 20), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 16, 20), result.stamp(NodeView.DEFAULT));
         }
     }
 
@@ -238,7 +239,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseLongSnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 48, 64), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 48, 64), result.stamp(NodeView.DEFAULT));
         }
     }
 
@@ -253,7 +254,7 @@
         /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */
         ValueNode result = parseAndInline("scanReverseLongEmptySnippet", BitScanReverseNode.class);
         if (result != null) {
-            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp());
+            Assert.assertEquals(StampFactory.forInteger(JavaKind.Int, 24, 64), result.stamp(NodeView.DEFAULT));
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactFoldTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ReturnNode;
@@ -95,7 +96,7 @@
         ValueNode node = findNode(graph);
         boolean overflowExpected = node instanceof IntegerExactArithmeticNode;
 
-        IntegerStamp resultStamp = (IntegerStamp) node.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) node.stamp(NodeView.DEFAULT);
         operation.verifyOverflow(lowerBoundA, upperBoundA, lowerBoundB, upperBoundB, bits, overflowExpected, resultStamp);
     }
 
@@ -120,7 +121,7 @@
         ValueNode node = findNode(graph);
         boolean overflowExpected = node instanceof IntegerExactArithmeticSplitNode;
 
-        IntegerStamp resultStamp = (IntegerStamp) node.stamp();
+        IntegerStamp resultStamp = (IntegerStamp) node.stamp(NodeView.DEFAULT);
         operation.verifyOverflow(lowerBoundA, upperBoundA, lowerBoundB, upperBoundB, bits, overflowExpected, resultStamp);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
@@ -50,8 +51,12 @@
  */
 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
 
+    protected StructuredGraph testGraph(final String snippet) {
+        return testGraph(snippet, null);
+    }
+
     @SuppressWarnings("try")
-    protected StructuredGraph testGraph(final String snippet) {
+    protected StructuredGraph testGraph(final String snippet, String name) {
         DebugContext debug = getDebugContext();
         try (DebugContext.Scope s = debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
@@ -69,7 +74,20 @@
                 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
             }
             assertNotInGraph(graph, MacroNode.class);
-            assertNotInGraph(graph, Invoke.class);
+            if (name != null) {
+                for (Node node : graph.getNodes()) {
+                    if (node instanceof Invoke) {
+                        Invoke invoke = (Invoke) node;
+                        if (invoke.callTarget() instanceof MethodCallTargetNode) {
+                            MethodCallTargetNode call = (MethodCallTargetNode) invoke.callTarget();
+                            assertTrue(!call.targetMethod().getName().equals(name), "Unexpected invoke of intrinsic %s", call.targetMethod());
+                        }
+                    }
+
+                }
+            } else {
+                assertNotInGraph(graph, Invoke.class);
+            }
             return graph;
         } catch (Throwable e) {
             throw debug.handle(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MonitorTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MonitorTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -221,7 +221,8 @@
      * Reproduces issue reported in https://github.com/graalvm/graal-core/issues/201. The stamp in
      * the PiNode returned by {@link BoxingSnippets#longValueOf} was overwritten when the node was
      * subsequently canonicalized because {@code PiNode.computeValue()} ignored the
-     * {@link ValueNode#stamp()} field and used the {@code PiNode.piStamp} field.
+     * {@link ValueNode#stamp(org.graalvm.compiler.nodes.NodeView)} field and used the
+     * {@code PiNode.piStamp} field.
      */
     @Test
     public void test8() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ObjectAccessTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.api.replacements.Snippet;
 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.StructuredGraph.AllowAssumptions;
@@ -93,7 +94,7 @@
 
     private static void assertRead(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity) {
         JavaReadNode read = (JavaReadNode) graph.start().next();
-        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp(NodeView.DEFAULT).getStackKind());
 
         OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
         Assert.assertEquals(graph.getParameter(0), address.getBase());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PointerTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -24,6 +24,7 @@
 
 import org.graalvm.compiler.api.replacements.Snippet;
 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.StructuredGraph.AllowAssumptions;
@@ -105,12 +106,12 @@
         WordCastNode cast = (WordCastNode) graph.start().next();
 
         JavaReadNode read = (JavaReadNode) cast.next();
-        Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind());
+        Assert.assertEquals(kind.getStackKind(), read.stamp(NodeView.DEFAULT).getStackKind());
 
         OffsetAddressNode address = (OffsetAddressNode) read.getAddress();
         Assert.assertEquals(cast, address.getBase());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
+        Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
 
         Assert.assertEquals(locationIdentity, read.getLocationIdentity());
 
@@ -137,7 +138,7 @@
         OffsetAddressNode address = (OffsetAddressNode) write.getAddress();
         Assert.assertEquals(cast, address.getBase());
         Assert.assertEquals(graph.getParameter(0), cast.getInput());
-        Assert.assertEquals(target.wordJavaKind, cast.stamp().getStackKind());
+        Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
 
         Assert.assertEquals(locationIdentity, write.getLocationIdentity());
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SystemArrayCopyTest.java	Fri Dec 01 11:17:45 2017 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2014, 2014, 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.replacements.test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static java.lang.reflect.Modifier.isStatic;
+
+@RunWith(Parameterized.class)
+public class SystemArrayCopyTest extends GraalCompilerTest {
+
+    @Parameter(0) public Object src;
+    @Parameter(1) public Object dst;
+    @Parameter(2) public int len;
+    @Parameter(3) public String name;
+
+    @Parameters(name = "{3}")
+    public static Collection<Object[]> data() {
+        Object[] srcs = {new int[4], new double[4], new Integer[4], new Number[4], new String[4], new Object[]{"Graal", 0, 0, 0}, new Object()};
+        Object[] dsts = {new int[4], new Number[4]};
+        int[] lens = {-1, 0, 2, 8};
+
+        ArrayList<Object[]> ret = new ArrayList<>(srcs.length * dsts.length * lens.length);
+        for (Object src : srcs) {
+            for (Object dst : dsts) {
+                for (int length : lens) {
+                    ret.add(new Object[]{src, dst, length, src.getClass().getSimpleName() + ", 0, " + dst.getClass().getSimpleName() + ", 0, " + length});
+                }
+            }
+        }
+        return ret;
+    }
+
+    public static void testArrayCopySnippet(Object src, Object dst, int length) {
+        System.arraycopy(src, 0, dst, 0, length);
+    }
+
+    private static final int PARAMETER_LENGTH = 3;
+    private Object[] argsToBind;
+
+    @Test
+    public void testArrayCopy() {
+        ResolvedJavaMethod method = getResolvedJavaMethod("testArrayCopySnippet");
+        Object receiver = method.isStatic() ? null : this;
+        Object[] args = {src, dst, len};
+
+        Result expect = executeExpected(method, receiver, args);
+        testAgainstExpected(method, expect, receiver, args);
+
+        // test composition of constant binding
+        for (int i = 1; i < (1 << PARAMETER_LENGTH); i++) {
+            argsToBind = new Object[PARAMETER_LENGTH];
+            for (int j = 0; j < PARAMETER_LENGTH; j++) {
+                if ((i & (1 << j)) != 0) {
+                    argsToBind[j] = args[j];
+                }
+            }
+            testAgainstExpected(method, expect, receiver, args);
+        }
+    }
+
+    @Override
+    protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
+        StructuredGraph graph = super.parse(builder, graphBuilderSuite);
+        if (argsToBind != null) {
+            ResolvedJavaMethod m = graph.method();
+            Object receiver = isStatic(m.getModifiers()) ? null : this;
+            Object[] args = argsWithReceiver(receiver, argsToBind);
+            JavaType[] parameterTypes = m.toParameterTypes();
+            assert parameterTypes.length == args.length;
+            for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
+                int index = param.index();
+                if (args[index] != null) {
+                    JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[index].getJavaKind(), args[index]);
+                    ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
+                    param.replaceAtUsages(replacement);
+                }
+            }
+        }
+        return graph;
+    }
+
+    @Override
+    protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
+        return super.getCode(method, graph, true, installAsDefault, options);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Fri Dec 01 11:17:45 2017 -0800
@@ -58,6 +58,7 @@
 import org.graalvm.compiler.nodes.FixedNode;
 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.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -113,7 +114,6 @@
 import org.graalvm.compiler.nodes.memory.WriteNode;
 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.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -247,7 +247,7 @@
                     indexOfSnippets.lower(node, tool);
                 }
             };
-            SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Char), n.stamp(), n.toArgumentArray());
+            SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Char), n.stamp(NodeView.DEFAULT), n.toArgumentArray());
             n.graph().add(snippetLower);
             n.graph().replaceFixedWithFixed(n, snippetLower);
         }
@@ -347,7 +347,7 @@
         ResolvedJavaField field = loadField.field();
         ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
         object = createNullCheckedValue(object, loadField, tool);
-        Stamp loadStamp = loadStamp(loadField.stamp(), getStorageKind(field));
+        Stamp loadStamp = loadStamp(loadField.stamp(NodeView.DEFAULT), getStorageKind(field));
 
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
@@ -419,7 +419,7 @@
         ValueNode array = loadIndexed.array();
         array = createNullCheckedValue(array, loadIndexed, tool);
         JavaKind elementKind = loadIndexed.elementKind();
-        Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind);
+        Stamp loadStamp = loadStamp(loadIndexed.stamp(NodeView.DEFAULT), elementKind);
 
         GuardingNode boundsCheck = getBoundsCheck(loadIndexed, array, tool);
         AddressNode address = createArrayIndexAddress(graph, array, elementKind, loadIndexed.index(), boundsCheck);
@@ -575,7 +575,7 @@
 
     protected AddressNode createUnsafeAddress(StructuredGraph graph, ValueNode object, ValueNode offset) {
         if (object.isConstant() && object.asConstant().isDefaultForKind()) {
-            return graph.unique(new RawAddressNode(offset));
+            return graph.addOrUniqueWithInputs(OffsetAddressNode.create(offset));
         } else {
             return graph.unique(new OffsetAddressNode(object, offset));
         }
@@ -584,7 +584,7 @@
     protected ReadNode createUnsafeRead(StructuredGraph graph, RawLoadNode load, GuardingNode guard) {
         boolean compressible = load.accessKind() == JavaKind.Object;
         JavaKind readKind = load.accessKind();
-        Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible);
+        Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, compressible);
         AddressNode address = createUnsafeAddress(graph, load.object(), load.offset());
         ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
         if (guard == null) {
@@ -603,8 +603,8 @@
         StructuredGraph graph = load.graph();
         JavaKind readKind = load.getKind();
         assert readKind != JavaKind.Object;
-        Stamp loadStamp = loadStamp(load.stamp(), readKind, false);
-        AddressNode address = graph.unique(new RawAddressNode(load.getAddress()));
+        Stamp loadStamp = loadStamp(load.stamp(NodeView.DEFAULT), readKind, false);
+        AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(load.getAddress()));
         ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, BarrierType.NONE));
         // An unsafe read must not float otherwise it may float above
         // a test guaranteeing the read is safe.
@@ -639,7 +639,7 @@
         assert store.getValue().getStackKind() != JavaKind.Object;
         JavaKind valueKind = store.getKind();
         ValueNode value = implicitStoreConvert(graph, valueKind, store.getValue(), false);
-        AddressNode address = graph.unique(new RawAddressNode(store.getAddress()));
+        AddressNode address = graph.addOrUniqueWithInputs(OffsetAddressNode.create(store.getAddress()));
         WriteNode write = graph.add(new WriteNode(address, store.getLocationIdentity(), value, BarrierType.NONE));
         write.setStateAfter(store.stateAfter());
         graph.replaceFixedWithFixed(store, write);
@@ -648,7 +648,7 @@
     protected void lowerJavaReadNode(JavaReadNode read) {
         StructuredGraph graph = read.graph();
         JavaKind valueKind = read.getReadKind();
-        Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible());
+        Stamp loadStamp = loadStamp(read.stamp(NodeView.DEFAULT), valueKind, read.isCompressible());
 
         ReadNode memoryRead = graph.add(new ReadNode(read.getAddress(), read.getLocationIdentity(), loadStamp, read.getBarrierType()));
         GuardingNode guard = read.getGuard();
@@ -1041,7 +1041,7 @@
             arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
         }
 
-        LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength);
+        LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
         if (boundsCheck.isTautology()) {
             return null;
         }
@@ -1060,7 +1060,7 @@
         if (nullCheck == null) {
             return object;
         }
-        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
+        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp(NodeView.DEFAULT)).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
     }
 
     @Override
@@ -1069,10 +1069,10 @@
         ValueNode offset = ((OffsetAddressNode) address).getOffset();
 
         int base = arrayBaseOffset(elementKind);
-        ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(), base, graph)));
+        ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(NodeView.DEFAULT), base, graph)));
 
         int shift = CodeUtil.log2(arrayScalingFactor(elementKind));
         ValueNode ret = graph.unique(new RightShiftNode(scaledIndex, ConstantNode.forInt(shift, graph)));
-        return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph);
+        return IntegerConvertNode.convert(ret, StampFactory.forKind(JavaKind.Int), graph, NodeView.DEFAULT);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Fri Dec 01 11:17:45 2017 -0800
@@ -50,6 +50,7 @@
 import org.graalvm.compiler.nodes.KillingBeginNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.MergeNode;
+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;
@@ -271,12 +272,12 @@
         int argIndex = 0;
         if (!isStatic) {
             JavaKind expected = asKind(method.getDeclaringClass());
-            JavaKind actual = args[argIndex++].stamp().getStackKind();
+            JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
             assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
         }
         for (int i = 0; i != signature.getParameterCount(false); i++) {
             JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
-            JavaKind actual = args[argIndex++].stamp().getStackKind();
+            JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
             if (expected != actual) {
                 throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ShortCircuitOrNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -183,7 +184,7 @@
             }
             if (condition == null || (!(condition instanceof CompareNode)) || ((CompareNode) condition).getY() != testValue) {
                 // Re-use previously generated condition if the trueValue for the test is the same
-                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue, null);
+                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue, null, NodeView.DEFAULT);
             }
             return condition;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/MethodHandlePlugin.java	Fri Dec 01 11:17:45 2017 -0800
@@ -83,6 +83,10 @@
                     // As such, it needs to recursively inline everything.
                     inlineEverything = args.length != argumentsList.size();
                 }
+                if (inlineEverything && !callTarget.targetMethod().hasBytecodes()) {
+                    // we need to force-inline but we can not, leave the invoke as-is
+                    return false;
+                }
                 b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), argumentsList.toArray(new ValueNode[argumentsList.size()]), inlineEverything);
             }
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java	Fri Dec 01 11:17:45 2017 -0800
@@ -63,6 +63,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.SimplifyingGraphDecoder;
@@ -583,7 +584,7 @@
             return callTarget.targetMethod();
         }
 
-        SpecialCallTargetCacheKey key = new SpecialCallTargetCacheKey(callTarget.invokeKind(), callTarget.targetMethod(), invokeData.contextType, callTarget.receiver().stamp());
+        SpecialCallTargetCacheKey key = new SpecialCallTargetCacheKey(callTarget.invokeKind(), callTarget.targetMethod(), invokeData.contextType, callTarget.receiver().stamp(NodeView.DEFAULT));
         Object specialCallTarget = specialCallTargetCache.get(key);
         if (specialCallTarget == null) {
             specialCallTarget = MethodCallTargetNode.devirtualizeCall(key.invokeKind, key.targetMethod, key.contextType, graph.getAssumptions(),
@@ -1066,7 +1067,7 @@
                 assert !methodScope.isInlinedMethod();
                 GraphBuilderContext graphBuilderContext = new PENonAppendGraphBuilderContext(methodScope, null);
                 Node result = parameterPlugin.interceptParameter(graphBuilderContext, param.index(),
-                                StampPair.create(param.stamp(), param.uncheckedStamp()));
+                                StampPair.create(param.stamp(NodeView.DEFAULT), param.uncheckedStamp()));
                 if (result != null) {
                     return result;
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Fri Dec 01 11:17:45 2017 -0800
@@ -83,6 +83,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode.Placeholder;
@@ -750,7 +751,7 @@
                         nodeReplacements.put(parameter, placeholder);
                         placeholders[i] = placeholder;
                     } else if (args.info.isNonNullParameter(i)) {
-                        parameter.setStamp(parameter.stamp().join(StampFactory.objectNonNull()));
+                        parameter.setStamp(parameter.stamp(NodeView.DEFAULT).join(StampFactory.objectNonNull()));
                     }
                 }
             }
@@ -785,7 +786,8 @@
                             if (usage instanceof LoadIndexedNode) {
                                 LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;
                                 debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "Before replacing %s", loadIndexed);
-                                LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp()));
+                                LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(
+                                                new LoadSnippetVarargParameterNode(params, loadIndexed.index(), loadIndexed.stamp(NodeView.DEFAULT)));
                                 snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
                                 debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "After replacing %s", loadIndexed);
                             } else if (usage instanceof StoreIndexedNode) {
@@ -829,7 +831,7 @@
             for (Node node : snippetCopy.getNodes()) {
                 if (node instanceof ValueNode) {
                     ValueNode valueNode = (ValueNode) node;
-                    if (valueNode.stamp() == PlaceholderStamp.singleton()) {
+                    if (valueNode.stamp(NodeView.DEFAULT) == PlaceholderStamp.singleton()) {
                         curPlaceholderStampedNodes.add(valueNode);
                     }
                 }
@@ -1502,7 +1504,7 @@
     private void updateStamps(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
         for (ValueNode node : placeholderStampedNodes) {
             ValueNode dup = (ValueNode) duplicates.get(node);
-            Stamp replaceeStamp = replacee.stamp();
+            Stamp replaceeStamp = replacee.stamp(NodeView.DEFAULT);
             if (node instanceof Placeholder) {
                 Placeholder placeholderDup = (Placeholder) dup;
                 placeholderDup.makeReplacement(replaceeStamp);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Fri Dec 01 11:17:45 2017 -0800
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.FixedGuardNode;
 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.calc.AbsNode;
@@ -296,14 +297,14 @@
         r.register2("divideUnsigned", type, type, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) {
-                b.push(kind, b.append(new UnsignedDivNode(dividend, divisor).canonical(null)));
+                b.push(kind, b.append(UnsignedDivNode.create(dividend, divisor, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register2("remainderUnsigned", type, type, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) {
-                b.push(kind, b.append(new UnsignedRemNode(dividend, divisor).canonical(null)));
+                b.push(kind, b.append(UnsignedRemNode.create(dividend, divisor, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -344,14 +345,14 @@
         r.register1("floatToRawIntBits", float.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Int, b.append(new ReinterpretNode(JavaKind.Int, value).canonical(null)));
+                b.push(JavaKind.Int, b.append(ReinterpretNode.create(JavaKind.Int, value, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register1("intBitsToFloat", int.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Float, b.append(new ReinterpretNode(JavaKind.Float, value).canonical(null)));
+                b.push(JavaKind.Float, b.append(ReinterpretNode.create(JavaKind.Float, value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -362,14 +363,14 @@
         r.register1("doubleToRawLongBits", double.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Long, b.append(new ReinterpretNode(JavaKind.Long, value).canonical(null)));
+                b.push(JavaKind.Long, b.append(ReinterpretNode.create(JavaKind.Long, value, NodeView.DEFAULT)));
                 return true;
             }
         });
         r.register1("longBitsToDouble", long.class, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Double, b.append(new ReinterpretNode(JavaKind.Double, value).canonical(null)));
+                b.push(JavaKind.Double, b.append(ReinterpretNode.create(JavaKind.Double, value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -421,7 +422,7 @@
         r.register1("sqrt", Double.TYPE, new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                b.push(JavaKind.Double, b.append(new SqrtNode(value).canonical(null)));
+                b.push(JavaKind.Double, b.append(SqrtNode.create(value, NodeView.DEFAULT)));
                 return true;
             }
         });
@@ -470,7 +471,7 @@
                 cond = cond.negate();
             }
 
-            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs);
+            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs, NodeView.DEFAULT);
             b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue));
             return true;
         }
@@ -521,7 +522,7 @@
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 ValueNode object = receiver.get();
-                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), GraphUtil.originalValue(object));
+                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object));
                 if (folded != null) {
                     b.addPush(JavaKind.Object, folded);
                 } else {
@@ -892,7 +893,8 @@
                         } else if (falseCount == 0 || trueCount == 0) {
                             boolean expected = falseCount == 0;
                             LogicNode condition = b.addWithInputs(
-                                            IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected))));
+                                            IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)),
+                                                            NodeView.DEFAULT));
                             b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true));
                             newResult = b.add(ConstantNode.forBoolean(expected));
                         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,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.ValueNode;
 import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.memory.MemoryAccess;
@@ -173,7 +174,7 @@
                             allEqual = false;
                         }
                     }
-                    if (entry1.stamp().alwaysDistinct(entry2.stamp())) {
+                    if (entry1.stamp(NodeView.DEFAULT).alwaysDistinct(entry2.stamp(NodeView.DEFAULT))) {
                         // the contents are different
                         tool.replaceWithValue(ConstantNode.forBoolean(false, graph()));
                         return;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.nodes.DeoptimizingNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
 import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
@@ -164,8 +165,8 @@
      * Returns true if this copy doesn't require store checks. Trivially true for primitive arrays.
      */
     public boolean isExact() {
-        ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp());
-        ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp());
+        ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp(NodeView.DEFAULT));
+        ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp(NodeView.DEFAULT));
         if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
             return false;
         }
@@ -173,7 +174,7 @@
             return true;
         }
 
-        if (StampTool.isExactType(getDestination().stamp())) {
+        if (StampTool.isExactType(getDestination().stamp(NodeView.DEFAULT))) {
             if (destType != null && destType.isAssignableFrom(srcType)) {
                 return true;
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -65,7 +66,7 @@
     }
 
     protected Stamp computeStamp(ValueNode object) {
-        Stamp objectStamp = object.stamp();
+        Stamp objectStamp = object.stamp(NodeView.DEFAULT);
         if (objectStamp instanceof ObjectStamp) {
             objectStamp = objectStamp.join(StampFactory.objectNonNull());
         }
@@ -116,7 +117,7 @@
                 tool.replaceWithVirtual(newVirtual);
             }
         } else {
-            ResolvedJavaType type = getConcreteType(originalAlias.stamp());
+            ResolvedJavaType type = getConcreteType(originalAlias.stamp(NodeView.DEFAULT));
             if (type != null && !type.isArray()) {
                 VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true);
                 ResolvedJavaField[] fields = newVirtual.getFields();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,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.calc.BinaryNode;
 import org.graalvm.compiler.nodes.calc.FloatDivNode;
@@ -86,13 +87,13 @@
 
     @Override
     public Stamp foldStamp(Stamp stampX, Stamp stampY) {
-        return stamp();
+        return stamp(NodeView.DEFAULT);
     }
 
     protected BinaryMathIntrinsicNode(ValueNode forX, ValueNode forY, BinaryOperation op) {
         super(TYPE, StampFactory.forKind(JavaKind.Double), forX, forY);
-        assert forX.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(forX.stamp()) == 64;
-        assert forY.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(forY.stamp()) == 64;
+        assert forX.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(forX.stamp(NodeView.DEFAULT)) == 64;
+        assert forY.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(forY.stamp(NodeView.DEFAULT)) == 64;
         this.operation = op;
     }
 
@@ -118,6 +119,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        NodeView view = NodeView.from(tool);
         ValueNode c = tryConstantFold(forX, forY, getOperation());
         if (c != null) {
             return c;
@@ -150,8 +152,8 @@
             }
 
             // x**0.5 = sqrt(x)
-            if (yValue == 0.5D && x.stamp() instanceof FloatStamp && ((FloatStamp) x.stamp()).lowerBound() >= 0.0D) {
-                return new SqrtNode(x);
+            if (yValue == 0.5D && x.stamp(view) instanceof FloatStamp && ((FloatStamp) x.stamp(view)).lowerBound() >= 0.0D) {
+                return SqrtNode.create(x, view);
             }
         }
         return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitCountNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -48,7 +49,7 @@
     public static final NodeClass<BitCountNode> TYPE = NodeClass.create(BitCountNode.class);
 
     public BitCountNode(ValueNode value) {
-        super(TYPE, computeStamp(value.stamp(), value), value);
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), value), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
@@ -59,7 +60,7 @@
     }
 
     static Stamp computeStamp(Stamp newStamp, ValueNode theValue) {
-        assert newStamp.isCompatible(theValue.stamp());
+        assert newStamp.isCompatible(theValue.stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         assert (valueStamp.downMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.downMask();
         assert (valueStamp.upMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.upMask();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanForwardNode.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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -53,13 +54,13 @@
     public static final NodeClass<BitScanForwardNode> TYPE = NodeClass.create(BitScanForwardNode.class);
 
     public BitScanForwardNode(ValueNode value) {
-        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp(NodeView.DEFAULT)).getBits()), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         int min;
         int max;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BitScanReverseNode.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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -53,13 +54,13 @@
     public static final NodeClass<BitScanReverseNode> TYPE = NodeClass.create(BitScanReverseNode.class);
 
     public BitScanReverseNode(ValueNode value) {
-        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+        super(TYPE, StampFactory.forInteger(JavaKind.Int, 0, ((PrimitiveStamp) value.stamp(NodeView.DEFAULT)).getBits()), value);
         assert value.getStackKind() == JavaKind.Int || value.getStackKind() == JavaKind.Long;
     }
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         int min;
         int max;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.GuardNode;
 import org.graalvm.compiler.nodes.InvokeNode;
 import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -263,7 +264,7 @@
                 // Try to get the most accurate receiver type
                 if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
                     ValueNode receiver = getReceiver(originalArguments);
-                    TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp());
+                    TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp(NodeView.DEFAULT));
                     if (receiverType != null) {
                         concreteMethod = receiverType.getType().findUniqueConcreteMethod(target);
                     }
@@ -317,7 +318,7 @@
              * type information anyway.
              */
             if (targetType != null && !targetType.getType().isPrimitive() && !argument.getStackKind().isPrimitive()) {
-                ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp());
+                ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp(NodeView.DEFAULT));
                 if (argumentType == null || (argumentType.isAssignableFrom(targetType.getType()) && !argumentType.equals(targetType.getType()))) {
                     LogicNode inst = InstanceOfNode.createAllowNull(targetType, argument, null, null);
                     assert !inst.isAlive();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReadRegisterNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
@@ -82,7 +83,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool generator) {
-        LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+        LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         Value result = register.asValue(kind);
         if (incoming) {
             generator.getLIRGeneratorTool().emitIncomingValues(new Value[]{result});
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReverseBytesNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ReverseBytesNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 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.UnaryNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -54,7 +55,7 @@
 
     @Override
     public Stamp foldStamp(Stamp newStamp) {
-        assert newStamp.isCompatible(getValue().stamp());
+        assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
         IntegerStamp valueStamp = (IntegerStamp) newStamp;
         if (getStackKind() == JavaKind.Int) {
             long mask = CodeUtil.mask(JavaKind.Int.getBitCount());
@@ -62,7 +63,7 @@
         } else if (getStackKind() == JavaKind.Long) {
             return IntegerStamp.stampForMask(valueStamp.getBits(), Long.reverse(valueStamp.downMask()), Long.reverse(valueStamp.upMask()));
         } else {
-            return stamp();
+            return stamp(NodeView.DEFAULT);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,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.calc.UnaryNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -106,8 +107,8 @@
     }
 
     protected UnaryMathIntrinsicNode(ValueNode value, UnaryOperation op) {
-        super(TYPE, computeStamp(value.stamp(), op), value);
-        assert value.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp()) == 64;
+        super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), op), value);
+        assert value.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp(NodeView.DEFAULT)) == 64;
         this.operation = op;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -36,6 +36,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -54,8 +55,8 @@
 
     public IntegerAddExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -132,7 +133,7 @@
                 return forX;
             }
         }
-        if (!IntegerStamp.addCanOverflow((IntegerStamp) forX.stamp(), (IntegerStamp) forY.stamp())) {
+        if (!IntegerStamp.addCanOverflow((IntegerStamp) forX.stamp(NodeView.DEFAULT), (IntegerStamp) forY.stamp(NodeView.DEFAULT))) {
             return new AddNode(forX, forY).canonical(tool);
         }
         return this;
@@ -159,7 +160,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerAddExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -49,7 +50,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.addCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.addCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             AddNode replacement = graph().unique(new AddNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -48,8 +49,8 @@
 
     public IntegerMulExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -76,10 +77,10 @@
                 return forX;
             }
             if (c == 0) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
             }
         }
-        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(NodeView.DEFAULT), (IntegerStamp) y.stamp(NodeView.DEFAULT))) {
             return new MulNode(x, y).canonical(tool);
         }
         return this;
@@ -104,7 +105,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerMulExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -51,7 +52,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.multiplicationCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             MulNode replacement = graph().unique(new MulNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulHighNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulHighNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.BinaryArithmeticNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -81,7 +82,7 @@
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
                 if (i == 0 || i == 1) {
-                    return ConstantNode.forIntegerStamp(self.stamp(), 0);
+                    return ConstantNode.forIntegerStamp(self.stamp(NodeView.DEFAULT), 0);
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -49,8 +50,8 @@
 
     public IntegerSubExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+        setStamp(x.stamp(NodeView.DEFAULT).unrestricted());
+        assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp;
     }
 
     @Override
@@ -67,7 +68,7 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forIntegerStamp(stamp(), 0);
+            return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
         }
         if (forX.isConstant() && forY.isConstant()) {
             return canonicalXYconstant(forX, forY);
@@ -77,7 +78,7 @@
                 return forX;
             }
         }
-        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(NodeView.DEFAULT), (IntegerStamp) y.stamp(NodeView.DEFAULT))) {
             return new SubNode(x, y).canonical(tool);
         }
         return this;
@@ -102,7 +103,7 @@
 
     @Override
     public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt));
+        return graph().add(new IntegerSubExactSplitNode(stamp(NodeView.DEFAULT), getX(), getY(), next, deopt));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -49,7 +50,8 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(), (IntegerStamp) y.stamp())) {
+        NodeView view = NodeView.from(tool);
+        if (!IntegerStamp.subtractionCanOverflow((IntegerStamp) x.stamp(view), (IntegerStamp) y.stamp(view))) {
             tool.deleteBranch(overflowSuccessor);
             tool.addToWorkList(next);
             SubNode replacement = graph().unique(new SubNode(x, y));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,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.calc.BinaryArithmeticNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -81,7 +82,7 @@
             if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
                 long i = ((PrimitiveConstant) c).asLong();
                 if (i == 0 || i == 1) {
-                    return ConstantNode.forIntegerStamp(self.stamp(), 0);
+                    return ConstantNode.forIntegerStamp(self.stamp(NodeView.DEFAULT), 0);
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Fri Dec 01 11:17:45 2017 -0800
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.IfNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
@@ -228,7 +229,8 @@
      */
     public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) {
         assert node != null && replacement != null : node + " " + replacement;
-        assert node.stamp().isCompatible(replacement.stamp()) : "Replacement node stamp not compatible " + node.stamp() + " vs " + replacement.stamp();
+        assert node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " +
+                        replacement.stamp(NodeView.DEFAULT);
         add("replace at usages", (graph, obsoleteNodes) -> {
             assert node.isAlive();
             ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement);
@@ -244,8 +246,8 @@
              * to improve the stamp information of the read. Such a read might later be replaced
              * with a read with a less precise stamp.
              */
-            if (!node.stamp().equals(replacementNode.stamp())) {
-                replacementNode = graph.unique(new PiNode(replacementNode, node.stamp()));
+            if (!node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
+                replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
             }
             node.replaceAtUsages(replacementNode);
             if (node instanceof FixedWithNextNode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationBlockState.java	Fri Dec 01 11:17:45 2017 -0800
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
@@ -127,7 +128,7 @@
             VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
             for (int i = 0; i < instance.entryCount(); i++) {
                 JavaKind declaredKind = instance.field(i).getJavaKind();
-                if (declaredKind == stampToJavaKind(values.get(i).stamp())) {
+                if (declaredKind == stampToJavaKind(values.get(i).stamp(NodeView.DEFAULT))) {
                     // We won't cache unaligned field writes upon instantiation unless we add
                     // support for non-array objects in PEReadEliminationClosure.processUnsafeLoad.
                     readCache.put(new ReadCacheEntry(new FieldLocationIdentity(instance.field(i)), representation, -1, declaredKind, false), values.get(i));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java	Fri Dec 01 11:17:45 2017 -0800
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
@@ -189,7 +190,7 @@
                 ValueNode object = GraphUtil.unproxify(load.object());
                 LocationIdentity location = NamedLocationIdentity.getArrayLocation(componentKind);
                 ValueNode cachedValue = state.getReadCache(object, location, index, accessKind, this);
-                assert cachedValue == null || load.stamp().isCompatible(cachedValue.stamp()) : "The RawLoadNode's stamp is not compatible with the cached value.";
+                assert cachedValue == null || load.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT)) : "The RawLoadNode's stamp is not compatible with the cached value.";
                 if (cachedValue != null) {
                     effects.replaceAtUsages(load, cachedValue, load);
                     addScalarAlias(load, cachedValue);
@@ -399,7 +400,7 @@
                     // e.g. unsafe loads / stores with different access kinds have different stamps
                     // although location, object and offset are the same, in this case we cannot
                     // create a phi nor can we set a common value
-                    if (otherValue == null || !value.stamp().isCompatible(otherValue.stamp())) {
+                    if (otherValue == null || !value.stamp(NodeView.DEFAULT).isCompatible(otherValue.stamp(NodeView.DEFAULT))) {
                         value = null;
                         phi = false;
                         break;
@@ -409,11 +410,11 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getPhi(key, value.stamp().unrestricted());
+                    PhiNode phiNode = getPhi(key, value.stamp(NodeView.DEFAULT).unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         ValueNode v = states.get(i).getReadCache(key.object, key.identity, key.index, key.kind, PEReadEliminationClosure.this);
-                        assert phiNode.stamp().isCompatible(v.stamp()) : "Cannot create read elimination phi for inputs with incompatible stamps.";
+                        assert phiNode.stamp(NodeView.DEFAULT).isCompatible(v.stamp(NodeView.DEFAULT)) : "Cannot create read elimination phi for inputs with incompatible stamps.";
                         setPhiInput(phiNode, i, v);
                     }
                     newState.readCache.put(key, phiNode);
@@ -444,13 +445,13 @@
                     ValueNode value = states.get(i).getReadCache(getPhiValueAt(phi, i), identity, index, kind, PEReadEliminationClosure.this);
                     // e.g. unsafe loads / stores with same identity and different access kinds see
                     // mergeReadCache(states)
-                    if (value == null || !values[i - 1].stamp().isCompatible(value.stamp())) {
+                    if (value == null || !values[i - 1].stamp(NodeView.DEFAULT).isCompatible(value.stamp(NodeView.DEFAULT))) {
                         return;
                     }
                     values[i] = value;
                 }
 
-                PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index, kind, overflowAccess), values[0].stamp().unrestricted());
+                PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index, kind, overflowAccess), values[0].stamp(NodeView.DEFAULT).unrestricted());
                 mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
                 for (int i = 0; i < values.length; i++) {
                     setPhiInput(phiNode, i, values[i]);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Fri Dec 01 11:17:45 2017 -0800
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -877,12 +878,12 @@
                         if (phis[valueIndex] == null) {
                             ValueNode field = states[i].getObjectState(getObject.applyAsInt(i)).getEntry(valueIndex);
                             if (values[valueIndex] != field) {
-                                phis[valueIndex] = createValuePhi(values[valueIndex].stamp().unrestricted());
+                                phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
                             }
                         }
                     }
-                    if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) {
-                        phis[valueIndex] = createValuePhi(values[valueIndex].stamp().unrestricted());
+                    if (phis[valueIndex] != null && !phis[valueIndex].stamp(NodeView.DEFAULT).isCompatible(values[valueIndex].stamp(NodeView.DEFAULT))) {
+                        phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
                     }
                     if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
                         // skip an entry after a long/double value that occupies two int slots
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ReadEliminationClosure.java	Fri Dec 01 11:17:45 2017 -0800
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.LoopExitNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -97,7 +98,7 @@
                 LoadCacheEntry identifier = new LoadCacheEntry(object, new FieldLocationIdentity(access.field()));
                 ValueNode cachedValue = state.getCacheEntry(identifier);
                 if (node instanceof LoadFieldNode) {
-                    if (cachedValue != null && access.stamp().isCompatible(cachedValue.stamp())) {
+                    if (cachedValue != null && access.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT))) {
                         effects.replaceAtUsages(access, cachedValue, access);
                         addScalarAlias(access, cachedValue);
                         deleted = true;
@@ -196,7 +197,7 @@
     }
 
     private static boolean areValuesReplaceable(ValueNode originalValue, ValueNode replacementValue, boolean considerGuards) {
-        return originalValue.stamp().isCompatible(replacementValue.stamp()) &&
+        return originalValue.stamp(NodeView.DEFAULT).isCompatible(replacementValue.stamp(NodeView.DEFAULT)) &&
                         (!considerGuards || (getGuard(originalValue) == null || getGuard(originalValue) == getGuard(replacementValue)));
     }
 
@@ -269,7 +270,7 @@
                     // E.g. unsafe loads / stores with different access kinds have different stamps
                     // although location, object and offset are the same. In this case we cannot
                     // create a phi nor can we set a common value.
-                    if (otherValue == null || !value.stamp().isCompatible(otherValue.stamp())) {
+                    if (otherValue == null || !value.stamp(NodeView.DEFAULT).isCompatible(otherValue.stamp(NodeView.DEFAULT))) {
                         value = null;
                         phi = false;
                         break;
@@ -279,11 +280,11 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getCachedPhi(key, value.stamp().unrestricted());
+                    PhiNode phiNode = getCachedPhi(key, value.stamp(NodeView.DEFAULT).unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         ValueNode v = states.get(i).getCacheEntry(key);
-                        assert phiNode.stamp().isCompatible(v.stamp()) : "Cannot create read elimination phi for inputs with incompatible stamps.";
+                        assert phiNode.stamp(NodeView.DEFAULT).isCompatible(v.stamp(NodeView.DEFAULT)) : "Cannot create read elimination phi for inputs with incompatible stamps.";
                         setPhiInput(phiNode, i, v);
                     }
                     newState.addCacheEntry(key, phiNode);
@@ -315,14 +316,14 @@
                     ValueNode value = states.get(i).getCacheEntry(identifier.duplicateWithObject(getPhiValueAt(phi, i)));
                     // e.g. unsafe loads / stores with same identity and different access kinds see
                     // mergeReadCache(states)
-                    if (value == null || !values[i - 1].stamp().isCompatible(value.stamp())) {
+                    if (value == null || !values[i - 1].stamp(NodeView.DEFAULT).isCompatible(value.stamp(NodeView.DEFAULT))) {
                         return;
                     }
                     values[i] = value;
                 }
 
                 CacheEntry<?> newIdentifier = identifier.duplicateWithObject(phi);
-                PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp().unrestricted());
+                PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp(NodeView.DEFAULT).unrestricted());
                 mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
                 for (int i = 0; i < values.length; i++) {
                     setPhiInput(phiNode, i, values[i]);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Fri Dec 01 11:17:45 2017 -0800
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
@@ -179,7 +180,7 @@
                 } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
                     // Splitting double word constant by storing over it with an int
                     getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
-                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false);
+                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false, NodeView.DEFAULT);
                     addNode(secondHalf);
                     state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
                 }
@@ -188,7 +189,7 @@
                 // Storing into second half of double, so replace previous value
                 ValueNode previous = getEntry(virtual, index - 1);
                 getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
-                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true);
+                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true, NodeView.DEFAULT);
                 addNode(firstHalf);
                 state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java	Fri Dec 01 14:19:16 2017 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java	Fri Dec 01 11:17:45 2017 -0800
@@ -38,6 +38,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.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@@ -73,17 +74,17 @@
     }
 
     public static WordCastNode addressToWord(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof AbstractPointerStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input);
     }
 
     public static WordCastNode objectToTrackedPointer(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof ObjectStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input, true);
     }
 
     public static WordCastNode objectToUntrackedPointer(ValueNode input, JavaKind wordKind) {
-        assert input.stamp() instanceof ObjectStamp;
+        assert input.stamp(NodeView.DEFAULT) instanceof ObjectStamp;
         return new WordCastNode(StampFactory.forKind(wordKind), input, false);
     }
 
@@ -108,13 +109,13 @@
             return input;
         }
 
-        assert !stamp().isCompatible(input.stamp());
+        assert !stamp(NodeView.DEFAULT).isCompatible(input.stamp(NodeView.DEFAULT));
         if (input.isConstant()) {
             /* Null pointers are uncritical for GC, so they can be constant folded. */
             if (input.asJavaConstant().isNull()) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
+                return ConstantNode.forIntegerStamp(stamp(NodeView.DEFAULT), 0);
             } else if (input.asJavaConstant().getJavaKind().isNumericInteger() && input.asJavaConstant().asLong() == 0) {
-                return ConstantNode.forConstant(stamp(), JavaConstant.NULL_POINTER, tool.getMetaAccess());
+                return ConstantNode.forConstant(stamp(NodeView.DEFAULT), JavaConstant.NULL_POINTER, tool.getMetaAccess());
             }
         }
 
@@ -124,7 +125,7 @@
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         Value value = generator.operand(input);
-        ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+        ValueKind<?> kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
         assert kind.getPlatformKind().getSizeInBytes() == value.getPlatformKind().getSizeInBytes();
 
         if (trackedPointer && LIRKind.isValue(kind) && !LIRKind.isValue(value)) {