MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / VisitAssignment

Method VisitAssignment

source/opt/ccp_pass.cpp:129–205  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

127}
128
129SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) {
130 assert(instr->result_id() != 0 &&
131 "Expecting an instruction that produces a result");
132
133 // If this is a copy operation, and the RHS is a known constant, assign its
134 // value to the LHS.
135 if (instr->opcode() == spv::Op::OpCopyObject) {
136 uint32_t rhs_id = instr->GetSingleWordInOperand(0);
137 auto it = values_.find(rhs_id);
138 if (it != values_.end()) {
139 if (IsVaryingValue(it->second)) {
140 return MarkInstructionVarying(instr);
141 } else {
142 uint32_t new_val = ComputeLatticeMeet(instr, it->second);
143 values_[instr->result_id()] = new_val;
144 return IsVaryingValue(new_val) ? SSAPropagator::kVarying
145 : SSAPropagator::kInteresting;
146 }
147 }
148 return SSAPropagator::kNotInteresting;
149 }
150
151 // Instructions with a RHS that cannot produce a constant are always varying.
152 if (!instr->IsFoldable()) {
153 return MarkInstructionVarying(instr);
154 }
155
156 // See if the RHS of the assignment folds into a constant value.
157 auto map_func = [this](uint32_t id) {
158 auto it = values_.find(id);
159 if (it == values_.end() || IsVaryingValue(it->second)) {
160 return id;
161 }
162 return it->second;
163 };
164 Instruction* folded_inst =
165 context()->get_instruction_folder().FoldInstructionToConstant(instr,
166 map_func);
167
168 if (folded_inst && context()->id_overflow()) {
169 return SSAPropagator::kFailed;
170 }
171 if (folded_inst != nullptr) {
172 // We do not want to change the body of the function by adding new
173 // instructions. When folding we can only generate new constants.
174 assert((folded_inst->IsConstant() ||
175 IsSpecConstantInst(folded_inst->opcode())) &&
176 "CCP is only interested in constant values.");
177 uint32_t new_val = ComputeLatticeMeet(instr, folded_inst->result_id());
178 values_[instr->result_id()] = new_val;
179 return IsVaryingValue(new_val) ? SSAPropagator::kVarying
180 : SSAPropagator::kInteresting;
181 }
182
183 // Conservatively mark this instruction as varying if any input id is varying.
184 if (!instr->WhileEachInId([this](uint32_t* op_id) {
185 auto iter = values_.find(*op_id);
186 if (iter != values_.end() && IsVaryingValue(iter->second)) return false;

Callers

nothing calls this directly

Calls 10

IsSpecConstantInstFunction · 0.85
IsFoldableMethod · 0.80
id_overflowMethod · 0.80
IsConstantMethod · 0.80
WhileEachInIdMethod · 0.80
result_idMethod · 0.45
opcodeMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected