/**
  * Modifies the {@link GraphBuilderConfiguration} to build extra {@linkplain DebugInfoMode#Simple
  * debug info} if the VM {@linkplain CompilerToVM#shouldDebugNonSafepoints() requests} it.
  *
  * @param gbs the current graph builder suite
  * @return a possibly modified graph builder suite
  */
 public static PhaseSuite<HighTierContext> withSimpleDebugInfoIfRequested(
     PhaseSuite<HighTierContext> gbs) {
   if (HotSpotGraalRuntime.runtime().getCompilerToVM().shouldDebugNonSafepoints()) {
     PhaseSuite<HighTierContext> newGbs = gbs.copy();
     GraphBuilderPhase graphBuilderPhase =
         (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous();
     GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig();
     GraphBuilderPhase newGraphBuilderPhase =
         new GraphBuilderPhase(graphBuilderConfig.withDebugInfoMode(DebugInfoMode.Simple));
     newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase);
     return newGbs;
   }
   return gbs;
 }
  protected PhaseSuite<HighTierContext> createGraphBuilderSuite(
      MetaAccessProvider metaAccess,
      ConstantReflectionProvider constantReflection,
      Replacements replacements) {
    PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
    GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
    if (InlineDuringParsing.getValue()) {
      config.setLoadFieldPlugin(
          new LoadFieldPlugin() {
            public boolean apply(
                GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
              if (receiver.isConstant()) {
                JavaConstant asJavaConstant = receiver.asJavaConstant();
                return tryConstantFold(
                    builder, metaAccess, constantReflection, field, asJavaConstant);
              }
              return false;
            }

            public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
              return tryConstantFold(builder, metaAccess, constantReflection, staticField, null);
            }
          });
      config.setInlineInvokePlugin(
          new InlineInvokePlugin() {
            public ResolvedJavaMethod getInlinedMethod(
                GraphBuilderContext builder,
                ResolvedJavaMethod method,
                ValueNode[] args,
                JavaType returnType,
                int depth) {
              ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method);
              if (subst != null) {
                return subst;
              }
              if (builder.parsingReplacement()
                  && method.getAnnotation(NodeIntrinsic.class) == null) {
                return method;
              }
              if (method.hasBytecodes()
                  && method.getCode().length <= TrivialInliningSize.getValue()
                  && depth < InlineDuringParsingMaxDepth.getValue()) {
                return method;
              }
              return null;
            }
          });
      config.setAnnotatedInvocationPlugin(
          new AnnotatedInvocationPlugin() {
            public boolean apply(
                GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) {
              if (builder.parsingReplacement()) {
                @SuppressWarnings("hiding")
                NodeIntrinsificationPhase intrinsifier = getIntrinsifier();
                NodeIntrinsic intrinsic = intrinsifier.getIntrinsic(method);
                if (intrinsic != null) {
                  Signature sig = method.getSignature();
                  Kind returnKind = sig.getReturnKind();
                  Stamp stamp = StampFactory.forKind(returnKind);
                  if (returnKind == Kind.Object) {
                    JavaType returnType = sig.getReturnType(method.getDeclaringClass());
                    if (returnType instanceof ResolvedJavaType) {
                      stamp = StampFactory.declared((ResolvedJavaType) returnType);
                    }
                  }

                  ValueNode res =
                      intrinsifier.createIntrinsicNode(
                          Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic);
                  res = builder.append(res);
                  if (res.getKind().getStackKind() != Kind.Void) {
                    builder.push(returnKind.getStackKind(), res);
                  }
                  return true;
                } else if (intrinsifier.isFoldable(method)) {
                  ResolvedJavaType[] parameterTypes =
                      resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
                  JavaConstant constant =
                      intrinsifier.tryFold(Arrays.asList(args), parameterTypes, method);
                  if (!COULD_NOT_FOLD.equals(constant)) {
                    if (constant != null) {
                      // Replace the invoke with the result of the call
                      ConstantNode res =
                          builder.append(ConstantNode.forConstant(constant, getMetaAccess()));
                      builder.push(res.getKind().getStackKind(), builder.append(res));
                    } else {
                      // This must be a void invoke
                      assert method.getSignature().getReturnKind() == Kind.Void;
                    }
                    return true;
                  }
                }
              }
              return false;
            }
          });
    }
    suite.appendPhase(new GraphBuilderPhase(config));
    return suite;
  }