+STATIC OP*
+optimize_out_native_convert_function(pTHX_ OP* entersubop,
+ GV* namegv,
+ SV* protosv)
+{
+ /* Optimizes out an identity function, i.e., one that just returns its
+ * argument. The passed in function is assumed to be an identity function,
+ * with no checking. This is designed to be called for utf8_to_native()
+ * and native_to_utf8() on ASCII platforms, as they just return their
+ * arguments, but it could work on any such function.
+ *
+ * The code is mostly just cargo-culted from Memoize::Lift */
+
+ OP *pushop, *argop;
+ OP *parent;
+ SV* prototype = newSVpvs("$");
+
+ PERL_UNUSED_ARG(protosv);
+
+ assert(entersubop->op_type == OP_ENTERSUB);
+
+ entersubop = ck_entersub_args_proto(entersubop, namegv, prototype);
+ parent = entersubop;
+
+ SvREFCNT_dec(prototype);
+
+ pushop = cUNOPx(entersubop)->op_first;
+ if (! OpHAS_SIBLING(pushop)) {
+ parent = pushop;
+ pushop = cUNOPx(pushop)->op_first;
+ }
+ argop = OpSIBLING(pushop);
+
+ /* Carry on without doing the optimization if it is not something we're
+ * expecting, so continues to work */
+ if ( ! argop
+ || ! OpHAS_SIBLING(argop)
+ || OpHAS_SIBLING(OpSIBLING(argop))
+ ) {
+ return entersubop;
+ }
+
+ /* cut argop from the subtree */
+ (void)op_sibling_splice(parent, pushop, 1, NULL);
+
+ op_free(entersubop);
+ return argop;
+}
+