1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2018 Alyssa Rosenzweig
3bf215546Sopenharmony_ci * Copyright (C) 2019 Collabora, Ltd.
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22bf215546Sopenharmony_ci * SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "compiler.h"
26bf215546Sopenharmony_ci#include "midgard_ops.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_cibool
29bf215546Sopenharmony_cimidgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
30bf215546Sopenharmony_ci{
31bf215546Sopenharmony_ci        bool progress = false;
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci        mir_foreach_instr_in_block_safe(block, ins) {
34bf215546Sopenharmony_ci                if (ins->type != TAG_ALU_4) continue;
35bf215546Sopenharmony_ci                if (!OP_IS_MOVE(ins->op)) continue;
36bf215546Sopenharmony_ci                if (ins->is_pack) continue;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci                unsigned from = ins->src[1];
39bf215546Sopenharmony_ci                unsigned to = ins->dest;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci                /* We only work on pure SSA */
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci                if (to & PAN_IS_REG) continue;
44bf215546Sopenharmony_ci                if (from & PAN_IS_REG) continue;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci                /* Constant propagation is not handled here, either */
47bf215546Sopenharmony_ci                if (ins->has_inline_constant) continue;
48bf215546Sopenharmony_ci                if (ins->has_constants) continue;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci                /* Modifier propagation is not handled here */
51bf215546Sopenharmony_ci                if (mir_nontrivial_mod(ins, 1, false)) continue;
52bf215546Sopenharmony_ci                if (mir_nontrivial_outmod(ins)) continue;
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci                /* Shortened arguments (bias for textures, extra load/store
55bf215546Sopenharmony_ci                 * arguments, etc.) do not get a swizzle, only a start
56bf215546Sopenharmony_ci                 * component and even that is restricted. Fragment writeout
57bf215546Sopenharmony_ci                 * doesn't even get that much */
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci                bool skip = false;
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci                mir_foreach_instr_global(ctx, q) {
62bf215546Sopenharmony_ci                        bool is_tex = q->type == TAG_TEXTURE_4;
63bf215546Sopenharmony_ci                        bool is_ldst = q->type == TAG_LOAD_STORE_4;
64bf215546Sopenharmony_ci                        bool is_branch = q->compact_branch;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci                        if (!(is_tex || is_ldst || is_branch)) continue;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci                        /* For textures, we get a real swizzle for the
69bf215546Sopenharmony_ci                         * coordinate and the content. For stores, we get one.
70bf215546Sopenharmony_ci                         * For loads, we get none. */
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci                        unsigned start =
73bf215546Sopenharmony_ci                                is_tex ? 2 :
74bf215546Sopenharmony_ci                                OP_IS_STORE(q->op) ? 1 : 0;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci                        mir_foreach_src(q, s) {
77bf215546Sopenharmony_ci                                if ((s >= start) && q->src[s] == to) {
78bf215546Sopenharmony_ci                                        skip = true;
79bf215546Sopenharmony_ci                                        break;
80bf215546Sopenharmony_ci                                }
81bf215546Sopenharmony_ci                        }
82bf215546Sopenharmony_ci                }
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci                if (skip)
85bf215546Sopenharmony_ci                        continue;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci                if (ctx->blend_src1 == to)
88bf215546Sopenharmony_ci                        ctx->blend_src1 = from;
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci                /* We're clear -- rewrite, composing the swizzle */
91bf215546Sopenharmony_ci                mir_rewrite_index_src_swizzle(ctx, to, from, ins->swizzle[1]);
92bf215546Sopenharmony_ci                mir_remove_instruction(ins);
93bf215546Sopenharmony_ci                progress |= true;
94bf215546Sopenharmony_ci        }
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci        return progress;
97bf215546Sopenharmony_ci}
98