162 IR::MAU::StatefulAlu *salu;
163 const IR::Type *regtype;
164 const IR::Declaration_Instance *reg_action =
nullptr;
166 enum class param_t { VALUE, OUTPUT, HASH, LEARN, MATCH };
167 const std::vector<param_t> *param_types =
nullptr;
168 IR::MAU::SaluAction *action =
nullptr;
169 const IR::ParameterList *params =
nullptr;
174 const IR::MAU::SaluRegfileRow *regfile =
nullptr;
175 enum use_t { NONE, ALUHI, MEMLO, MEMHI, MEMALL, REGFILE } use = NONE;
176 LocalVar(
cstring name,
bool pair, use_t use = NONE,
177 const IR::MAU::SaluRegfileRow *regfile =
nullptr)
178 : name(name), pair(pair), regfile(regfile), use(use) {}
180 std::map<cstring, LocalVar> locals;
194 static bool islvalue(etype_t t) {
return t < IF; }
196 bool negate_regfile =
false;
197 bool alu_write[2] = {
false,
false};
200 int output_index = -1;
201 std::vector<const IR::MAU::SaluInstruction *> cmp_instr;
202 const IR::MAU::SaluInstruction *divmod_instr =
nullptr, *minmax_instr =
nullptr;
203 int minmax_width = -1;
204 const IR::Expression *predicate =
nullptr;
205 const IR::MAU::SaluInstruction *onebit =
nullptr;
206 bool onebit_cmpl =
false;
207 int address_subword = 0;
208 std::vector<IR::MAU::SaluInstruction *> outputs;
209 std::map<int, const IR::Expression *> output_address_subword_predicate;
210 IR::MAU::StatefulAlu::MathUnit math;
211 IR::MAU::SaluFunction *math_function =
nullptr;
212 bool assignDone =
false;
213 int comb_pred_width = 0;
214 IR::MAU::SaluAction::ReturnEnumEncoding *return_encoding =
nullptr;
215 int return_enum_word = -1;
216 bool split_ifs =
false;
217 std::map<int, const IR::Expression *> output_param_operands;
218 std::map<int, const IR::Expression *> output_predicates;
219 std::set<const IR::Expression *> or_targets;
225 struct AssignmentProperties {
226 const IR::Expression *predicate;
228 explicit AssignmentProperties(
const IR::Expression *pred,
const Util::SourceInfo &src)
229 : predicate(pred), srcInfo(src) {}
231 std::map<cstring, std::vector<AssignmentProperties>> written_dest;
232 const IR::AssignmentStatement *assig_st =
nullptr;
233 const IR::Expression *assig_pred =
nullptr;
234 void captureAssigstateProps();
235 void checkWriteAfterWrite();
237 bool isComplexInstruction(
const IR::Operation_Binary *op)
const;
238 void checkAndReportComplexInstruction(
const IR::Operation_Binary *op)
const;
247 void insert_instruction(
const IR::MAU::SaluInstruction *si);
249 void clearFuncState();
250 const IR::MAU::SaluInstruction *createInstruction();
251 bool applyArg(
const IR::PathExpression *,
cstring);
252 const IR::Expression *reuseCmp(
const IR::MAU::SaluInstruction *cmp,
int idx);
254 void splitWideInstructions();
255 void assignOutputAlus();
256 const IR::MAU::SaluInstruction *setup_output();
257 bool outputEnumAsPredicate(
const IR::Member *);
258 bool canBeIXBarExpr(
const IR::Expression *);
262 bool preorder(
const IR::Declaration_Instance *di)
override;
263 bool preorder(
const IR::Declaration_Variable *v)
override;
264 bool preorder(
const IR::Property *)
override { BUG(
"unconverted p4_14"); }
265 void postorder(
const IR::Property *)
override { BUG(
"unconverted p4_14"); }
266 bool preorder(
const IR::Function *)
override;
267 void postorder(
const IR::Function *)
override;
268 bool preorder(
const IR::Annotations *)
override {
return false; }
270 bool preorder(
const IR::AssignmentStatement *)
override;
271 bool preorder(
const IR::IfStatement *)
override;
272 bool preorder(
const IR::BlockStatement *)
override {
return true; }
273 bool preorder(
const IR::EmptyStatement *)
override {
return true; }
274 bool preorder(
const IR::Statement *s)
override {
275 error(
"%s: statement too complex for register action %s", s->srcInfo, s);
279 void doPrimary(
const IR::Expression *,
const IR::PathExpression *,
cstring);
280 bool preorder(
const IR::PathExpression *pe)
override;
281 bool preorder(
const IR::Member *m)
override;
282 bool preorder(
const IR::StructExpression *m)
override;
284 bool preorder(
const IR::Constant *)
override;
285 bool preorder(
const IR::BoolLiteral *)
override;
286 bool preorder(
const IR::AttribLocal *)
override { BUG(
"unconverted p4_14"); }
287 bool preorder(
const IR::Slice *)
override;
288 bool preorder(
const IR::MAU::Primitive *)
override;
289 bool preorder(
const IR::MAU::SaluRegfileRow *)
override;
290 bool preorder(
const IR::Operation::Relation *,
cstring op,
bool eq);
291 bool preorder(
const IR::Equ *r)
override {
return preorder(r,
"equ"_cs,
true); }
292 bool preorder(
const IR::Neq *r)
override {
return preorder(r,
"neq"_cs,
true); }
293 bool preorder(
const IR::Grt *r)
override {
return preorder(r,
"grt"_cs,
false); }
294 bool preorder(
const IR::Lss *r)
override {
return preorder(r,
"lss"_cs,
false); }
295 bool preorder(
const IR::Geq *r)
override {
return preorder(r,
"geq"_cs,
false); }
296 bool preorder(
const IR::Leq *r)
override {
return preorder(r,
"leq"_cs,
false); }
297 bool preorder(
const IR::Cast *)
override;
298 void postorder(
const IR::Cast *)
override;
299 bool preorder(
const IR::BFN::SignExtend *)
override;
300 bool preorder(
const IR::BFN::ReinterpretCast *)
override {
return true; }
301 void postorder(
const IR::BFN::ReinterpretCast *)
override;
302 bool preorder(
const IR::LNot *)
override {
return true; }
303 void postorder(
const IR::LNot *)
override;
304 bool preorder(
const IR::LAnd *)
override {
return true; }
305 void postorder(
const IR::LAnd *)
override;
306 bool preorder(
const IR::LOr *)
override {
return true; }
307 void postorder(
const IR::LOr *)
override;
308 bool preorder(
const IR::Mux *)
override;
309 bool preorder(
const IR::Add *)
override;
310 bool preorder(
const IR::AddSat *)
override;
311 bool preorder(
const IR::Sub *)
override;
312 bool preorder(
const IR::SubSat *)
override;
313 bool preorder(
const IR::Neg *)
override;
314 void postorder(
const IR::Neg *)
override;
315 bool preorder(
const IR::Cmpl *)
override {
return true; }
316 void postorder(
const IR::Cmpl *)
override;
317 bool preorder(
const IR::BAnd *)
override;
318 void postorder(
const IR::BAnd *)
override;
319 bool preorder(
const IR::BOr *)
override;
320 void postorder(
const IR::BOr *)
override;
321 bool preorder(
const IR::BXor *)
override;
322 void postorder(
const IR::BXor *)
override;
323 bool preorder(
const IR::Concat *)
override;
324 void postorder(
const IR::Concat *)
override;
325 bool divmod(
const IR::Operation::Binary *,
cstring op);
326 bool preorder(
const IR::Div *e)
override {
return divmod(e,
"div"_cs); }
327 bool preorder(
const IR::Mod *e)
override {
return divmod(e,
"mod"_cs); }
328 bool preorder(
const IR::Expression *e)
override {
329 error(
"%s: expression too complex for register action", e->srcInfo);
333 friend std::ostream &operator<<(std::ostream &, CreateSaluInstruction::LocalVar::use_t);
334 friend std::ostream &operator<<(std::ostream &, CreateSaluInstruction::etype_t);
335 static std::map<std::pair<cstring, cstring>, std::vector<param_t>> function_param_types;
339 if (
auto spec = salu->reg->type->to<IR::Type_Specialized>())
340 regtype = spec->arguments->at(0);
342 regtype = IR::Type::Bits::get(1);
343 visitDagOnce =
false;
410 struct return_enum_info_t {
413 const IR::MAU::SaluAction::ReturnEnumEncoding *encoding;
417 const IR::Type::Bits *pred_type;
421 bool preorder(
const IR::MAU::SaluAction *)
override;
422 bool preorder(
const IR::MAU::Action *)
override {
return false; }
425 struct UpdateEncodings :
public Transform {
427 const IR::BFN::Pipe *preorder(IR::BFN::Pipe *p)
override {
428 if (self.encodings.empty()) prune();
431 const IR::MAU::SaluAction *preorder(IR::MAU::SaluAction *)
override;
432 const IR::Operation::Relation *preorder(IR::Operation::Relation *)
override;
433 const IR::Expression *preorder(IR::Member *)
override;
434 const IR::Expression *preorder(IR::Expression *)
override;
435 const IR::BFN::ParserRVal *postorder(IR::BFN::SavedRVal *)
override;
439 struct ReplaceUpdatedEnumTypes :
public Transform {
441 const IR::Expression *postorder(IR::Expression *exp) {
442 visit(exp->type,
"type");
445 const IR::Type *preorder(IR::Type_Enum *enum_t) {
446 if (self.encodings.count(getOriginal<IR::Type_Enum>()))
return self.pred_type;
456 new FindEncodings(*
this),
457 new UpdateEncodings(*
this),
458 new ReplaceUpdatedEnumTypes(*
this),
460 pred_type_size = 1 << Device::statefulAluSpec().CmpUnits.size();
461 pred_type = IR::Type::Bits::get(pred_type_size);