• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008 Nicolai Haehnle.
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "radeon_program.h"
7 
8 #include <stdio.h>
9 
10 #include "radeon_compiler.h"
11 #include "radeon_dataflow.h"
12 
13 /**
14  * Transform the given clause in the following way:
15  *  1. Replace it with an empty clause
16  *  2. For every instruction in the original clause, try the given
17  *     transformations in order.
18  *  3. If one of the transformations returns GL_TRUE, assume that it
19  *     has emitted the appropriate instruction(s) into the new clause;
20  *     otherwise, copy the instruction verbatim.
21  *
22  * \note The transformation is currently not recursive; in other words,
23  * instructions emitted by transformations are not transformed.
24  *
25  * \note The transform is called 'local' because it can only look at
26  * one instruction at a time.
27  */
28 void
rc_local_transform(struct radeon_compiler * c,void * user)29 rc_local_transform(struct radeon_compiler *c, void *user)
30 {
31    struct radeon_program_transformation *transformations =
32       (struct radeon_program_transformation *)user;
33    struct rc_instruction *inst = c->Program.Instructions.Next;
34 
35    while (inst != &c->Program.Instructions) {
36       struct rc_instruction *current = inst;
37       int i;
38 
39       inst = inst->Next;
40 
41       for (i = 0; transformations[i].function; ++i) {
42          struct radeon_program_transformation *t = transformations + i;
43 
44          if (t->function(c, current, t->userData))
45             break;
46       }
47    }
48 }
49 
50 unsigned int
rc_find_free_temporary(struct radeon_compiler * c)51 rc_find_free_temporary(struct radeon_compiler *c)
52 {
53    /* Find the largest used temp index when called for the first time. */
54    if (c->max_temp_index == -1) {
55       for (struct rc_instruction *inst = c->Program.Instructions.Next;
56            inst != &c->Program.Instructions; inst = inst->Next) {
57          const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
58          if (opcode->HasDstReg && inst->U.I.DstReg.File == RC_FILE_TEMPORARY &&
59              inst->U.I.WriteALUResult == RC_ALURESULT_NONE &&
60              inst->U.I.DstReg.Index > c->max_temp_index)
61             c->max_temp_index = inst->U.I.DstReg.Index;
62       }
63    }
64 
65    c->max_temp_index++;
66    if (c->max_temp_index > RC_REGISTER_MAX_INDEX) {
67       rc_error(c, "Ran out of temporary registers\n");
68       return 0;
69    }
70    return c->max_temp_index;
71 }
72 
73 struct rc_instruction *
rc_alloc_instruction(struct radeon_compiler * c)74 rc_alloc_instruction(struct radeon_compiler *c)
75 {
76    struct rc_instruction *inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
77 
78    memset(inst, 0, sizeof(struct rc_instruction));
79 
80    inst->U.I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
81    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
82    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
83    inst->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZW;
84    inst->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZW;
85 
86    return inst;
87 }
88 
89 void
rc_insert_instruction(struct rc_instruction * after,struct rc_instruction * inst)90 rc_insert_instruction(struct rc_instruction *after, struct rc_instruction *inst)
91 {
92    inst->Prev = after;
93    inst->Next = after->Next;
94 
95    inst->Prev->Next = inst;
96    inst->Next->Prev = inst;
97 }
98 
99 struct rc_instruction *
rc_insert_new_instruction(struct radeon_compiler * c,struct rc_instruction * after)100 rc_insert_new_instruction(struct radeon_compiler *c, struct rc_instruction *after)
101 {
102    struct rc_instruction *inst = rc_alloc_instruction(c);
103 
104    rc_insert_instruction(after, inst);
105 
106    return inst;
107 }
108 
109 void
rc_remove_instruction(struct rc_instruction * inst)110 rc_remove_instruction(struct rc_instruction *inst)
111 {
112    inst->Prev->Next = inst->Next;
113    inst->Next->Prev = inst->Prev;
114 }
115 
116 /**
117  * Return the number of instructions in the program.
118  */
119 unsigned int
rc_recompute_ips(struct radeon_compiler * c)120 rc_recompute_ips(struct radeon_compiler *c)
121 {
122    unsigned int ip = 0;
123    struct rc_instruction *inst;
124 
125    for (inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
126       inst->IP = ip++;
127    }
128 
129    c->Program.Instructions.IP = 0xcafedead;
130 
131    return ip;
132 }
133