def dump_actions(json_dict, hlir, p4_v1_1=False, keep_pragmas=False):
    actions = []
    action_id = 0

    table_actions_set = get_p4_action_set(hlir)

    for action in table_actions_set:
        action_dict = OrderedDict()
        action_dict["name"] = action.name
        action_dict["id"] = action_id
        action_id += 1

        runtime_data = []
        param_with_bit_widths = OrderedDict()
        for param, width in zip(action.signature, action.signature_widths):
            if not width:  # pragma: no cover
                LOG_CRITICAL(
                    "unused parameter '{}' in action '{}' definition".format(
                        param, action.name))
            param_with_bit_widths[param] = width

            param_dict = OrderedDict()
            param_dict["name"] = param
            param_dict["bitwidth"] = width
            runtime_data.append(param_dict)
        action_dict["runtime_data"] = runtime_data

        def is_stack_ref(call_idx, arg_idx, primitive_name):
            # legacy case
            if not hasattr(action, "stack_indices"):  # pragma: no cover
                return (primitive_name in {"push", "pop"} and arg_idx == 0)
            stack_indices = action.stack_indices[call_idx]
            return (arg_idx in stack_indices)

        primitives = []
        for call_idx, call in enumerate(action.flat_call_sequence):
            primitive_dict = OrderedDict()

            if p4_v1_1 and type(call[0]) is p4.p4_extern_method:
                primitive_name = "_" + call[0].parent.extern_type.name \
                                 + "_" + call[0].name
                primitive_dict["op"] = primitive_name
                args = [call[0].parent.name] + call[1]
            else:
                primitive_name = call[0].name
                primitive_dict["op"] = primitive_name
                args = call[1]

            # backwards compatibility with older P4 programs
            if primitive_name == "modify_field" and len(args) == 3:
                LOG_WARNING(
                    "Your P4 program uses the modify_field() action primitive "
                    "with 3 arguments (aka masked modify), bmv2 does not "
                    "support it anymore and this compiler will replace your "
                    "modify_field(a, b, c) with "
                    "modify_field(a, (a & ~c) | (b & c))")
                Lexpr = p4.p4_expression(args[0], "&",
                                         p4.p4_expression(None, "~", args[2]))
                Rexpr = p4.p4_expression(args[1], "&", args[2])
                new_arg = p4.p4_expression(Lexpr, "|", Rexpr)
                args = [args[0], new_arg]

            primitive_args = []
            for arg_idx, arg in enumerate(args):
                arg_dict = OrderedDict()
                if type(arg) is int or type(arg) is long:
                    arg_dict["type"] = "hexstr"
                    arg_dict["value"] = format_hexstr(arg)
                elif type(arg) is p4.p4_sized_integer:
                    # TODO(antonin)
                    arg_dict["type"] = "hexstr"
                    arg_dict["value"] = format_hexstr(arg)
                elif type(arg) is p4.p4_field:
                    arg_dict["type"] = "field"
                    arg_dict["value"] = format_field_ref(arg)
                elif type(arg) is p4.p4_header_instance:
                    arg_dict["type"] = "header"
                    arg_dict["value"] = arg.name
                elif p4_v1_1 and type(arg) is p4.p4_header_stack:
                    arg_dict["type"] = "header_stack"
                    arg_dict["value"] = re.sub(r'\[.*\]', '', arg.name)
                elif type(arg) is p4.p4_signature_ref:
                    arg_dict["type"] = "runtime_data"
                    arg_dict["value"] = arg.idx
                elif type(arg) is p4.p4_field_list:
                    # hack for generate_digest calls
                    if primitive_name == "generate_digest":
                        id_ = field_list_to_learn_id(arg)
                    elif "clone" in primitive_name or\
                         primitive_name in {"resubmit", "recirculate"}:
                        id_ = field_list_to_id(arg)
                    arg_dict["type"] = "hexstr"
                    arg_dict["value"] = format_hexstr(id_)
                elif type(arg) is p4.p4_field_list_calculation:
                    arg_dict["type"] = "calculation"
                    arg_dict["value"] = arg.name
                elif type(arg) is p4.p4_meter:
                    arg_dict["type"] = "meter_array"
                    arg_dict["value"] = arg.name
                elif type(arg) is p4.p4_counter:
                    arg_dict["type"] = "counter_array"
                    arg_dict["value"] = arg.name
                elif type(arg) is p4.p4_register:
                    arg_dict["type"] = "register_array"
                    arg_dict["value"] = arg.name
                elif type(arg) is p4.p4_expression:
                    arg_dict["type"] = "expression"
                    arg_dict["value"] = dump_expression(arg)
                elif is_register_ref(arg):
                    arg_dict["type"] = "register"
                    arg_dict["value"] = format_register_ref(arg)
                elif p4_v1_1 and type(call[0]) is p4.p4_extern_method:
                    if arg == call[0].parent.name:
                        arg_dict["type"] = "extern"
                        arg_dict["value"] = arg
                else:  # pragma: no cover
                    LOG_CRITICAL("action arg type is not supported: %s",
                                 type(arg))

                if (not p4_v1_1)\
                   and is_stack_ref(call_idx, arg_idx, primitive_name):
                    assert(arg_dict["type"] == "header")
                    arg_dict["type"] = "header_stack"
                    arg_dict["value"] = re.sub(r'\[.*\]', '', arg_dict["value"])

                primitive_args.append(arg_dict)
            primitive_dict["parameters"] = primitive_args

            primitives.append(primitive_dict)

        action_dict["primitives"] = primitives

        if keep_pragmas:
            add_pragmas(action_dict, action)

        actions.append(action_dict)

    json_dict["actions"] = actions