Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/amd/compiler/aco_form_hard_clauses.cpp
4550 views
1
/*
2
* Copyright © 2020 Valve Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*
23
*/
24
25
#include "aco_builder.h"
26
#include "aco_ir.h"
27
28
#include <vector>
29
30
namespace aco {
31
namespace {
32
33
/* there can also be LDS and VALU clauses, but I don't see how those are interesting */
34
enum clause_type {
35
clause_vmem,
36
clause_flat,
37
clause_smem,
38
clause_other,
39
};
40
41
void
42
emit_clause(Builder& bld, unsigned num_instrs, aco_ptr<Instruction>* instrs)
43
{
44
unsigned start = 0;
45
46
/* skip any stores at the start */
47
for (; (start < num_instrs) && instrs[start]->definitions.empty(); start++)
48
bld.insert(std::move(instrs[start]));
49
50
unsigned end = start;
51
for (; (end < num_instrs) && !instrs[end]->definitions.empty(); end++)
52
;
53
unsigned clause_size = end - start;
54
55
if (clause_size > 1)
56
bld.sopp(aco_opcode::s_clause, -1, clause_size - 1);
57
58
for (unsigned i = start; i < num_instrs; i++)
59
bld.insert(std::move(instrs[i]));
60
}
61
62
} /* end namespace */
63
64
void
65
form_hard_clauses(Program* program)
66
{
67
for (Block& block : program->blocks) {
68
unsigned num_instrs = 0;
69
aco_ptr<Instruction> current_instrs[64];
70
clause_type current_type = clause_other;
71
72
std::vector<aco_ptr<Instruction>> new_instructions;
73
new_instructions.reserve(block.instructions.size());
74
Builder bld(program, &new_instructions);
75
76
for (unsigned i = 0; i < block.instructions.size(); i++) {
77
aco_ptr<Instruction>& instr = block.instructions[i];
78
79
clause_type type = clause_other;
80
if (instr->isVMEM() && !instr->operands.empty()) {
81
if (program->chip_class == GFX10 && instr->isMIMG() &&
82
get_mimg_nsa_dwords(instr.get()) > 0)
83
type = clause_other;
84
else
85
type = clause_vmem;
86
} else if (instr->isScratch() || instr->isGlobal()) {
87
type = clause_vmem;
88
} else if (instr->isFlat()) {
89
type = clause_flat;
90
} else if (instr->isSMEM() && !instr->operands.empty()) {
91
type = clause_smem;
92
}
93
94
if (type != current_type || num_instrs == 64 ||
95
(num_instrs && !should_form_clause(current_instrs[0].get(), instr.get()))) {
96
emit_clause(bld, num_instrs, current_instrs);
97
num_instrs = 0;
98
current_type = type;
99
}
100
101
if (type == clause_other) {
102
bld.insert(std::move(instr));
103
continue;
104
}
105
106
current_instrs[num_instrs++] = std::move(instr);
107
}
108
109
emit_clause(bld, num_instrs, current_instrs);
110
111
block.instructions = std::move(new_instructions);
112
}
113
}
114
} // namespace aco
115
116