144 IR::MAU::StatefulAlu *salu;
145 const IR::Type *regtype;
146 const IR::Declaration_Instance *reg_action =
nullptr;
148 enum class param_t { VALUE, OUTPUT, HASH, LEARN, MATCH };
149 const std::vector<param_t> *param_types =
nullptr;
150 IR::MAU::SaluAction *action =
nullptr;
151 const IR::ParameterList *params =
nullptr;
156 const IR::MAU::SaluRegfileRow *regfile =
nullptr;
157 enum use_t { NONE, ALUHI, MEMLO, MEMHI, MEMALL, REGFILE } use = NONE;
158 LocalVar(
cstring name,
bool pair, use_t use = NONE,
159 const IR::MAU::SaluRegfileRow *regfile =
nullptr)
160 : name(name), pair(pair), regfile(regfile), use(use) {}
162 std::map<cstring, LocalVar> locals;
176 static bool islvalue(etype_t t) {
return t < IF; }
178 bool negate_regfile =
false;
179 bool alu_write[2] = {
false,
false};
182 int output_index = -1;
183 std::vector<const IR::MAU::SaluInstruction *> cmp_instr;
184 const IR::MAU::SaluInstruction *divmod_instr =
nullptr, *minmax_instr =
nullptr;
185 int minmax_width = -1;
186 const IR::Expression *predicate =
nullptr;
187 const IR::MAU::SaluInstruction *onebit =
nullptr;
188 bool onebit_cmpl =
false;
189 int address_subword = 0;
190 std::vector<IR::MAU::SaluInstruction *> outputs;
191 std::map<int, const IR::Expression *> output_address_subword_predicate;
192 IR::MAU::StatefulAlu::MathUnit math;
193 IR::MAU::SaluFunction *math_function =
nullptr;
194 bool assignDone =
false;
195 int comb_pred_width = 0;
196 IR::MAU::SaluAction::ReturnEnumEncoding *return_encoding =
nullptr;
197 int return_enum_word = -1;
198 bool split_ifs =
false;
199 std::map<int, const IR::Expression *> output_param_operands;
200 std::map<int, const IR::Expression *> output_predicates;
201 std::set<const IR::Expression *> or_targets;
207 struct AssignmentProperties {
208 const IR::Expression *predicate;
210 explicit AssignmentProperties(
const IR::Expression *pred,
const Util::SourceInfo &src)
211 : predicate(pred), srcInfo(src) {}
213 std::map<cstring, std::vector<AssignmentProperties>> written_dest;
214 const IR::AssignmentStatement *assig_st =
nullptr;
215 const IR::Expression *assig_pred =
nullptr;
216 void captureAssigstateProps();
217 void checkWriteAfterWrite();
219 bool isComplexInstruction(
const IR::Operation_Binary *op)
const;
220 void checkAndReportComplexInstruction(
const IR::Operation_Binary *op)
const;
229 void insert_instruction(
const IR::MAU::SaluInstruction *si);
231 void clearFuncState();
232 const IR::MAU::SaluInstruction *createInstruction();
233 bool applyArg(
const IR::PathExpression *,
cstring);
234 const IR::Expression *reuseCmp(
const IR::MAU::SaluInstruction *cmp,
int idx);
236 void splitWideInstructions();
237 void assignOutputAlus();
238 const IR::MAU::SaluInstruction *setup_output();
239 bool outputEnumAsPredicate(
const IR::Member *);
240 bool canBeIXBarExpr(
const IR::Expression *);
244 bool preorder(
const IR::Declaration_Instance *di)
override;
245 bool preorder(
const IR::Declaration_Variable *v)
override;
246 bool preorder(
const IR::Property *)
override { BUG(
"unconverted p4_14"); }
247 void postorder(
const IR::Property *)
override { BUG(
"unconverted p4_14"); }
248 bool preorder(
const IR::Function *)
override;
249 void postorder(
const IR::Function *)
override;
250 bool preorder(
const IR::Annotation *)
override {
return false; }
252 bool preorder(
const IR::AssignmentStatement *)
override;
253 bool preorder(
const IR::IfStatement *)
override;
254 bool preorder(
const IR::BlockStatement *)
override {
return true; }
255 bool preorder(
const IR::EmptyStatement *)
override {
return true; }
256 bool preorder(
const IR::Statement *s)
override {
257 error(
"%s: statement too complex for register action %s", s->srcInfo, s);
261 void doPrimary(
const IR::Expression *,
const IR::PathExpression *,
cstring);
262 bool preorder(
const IR::PathExpression *pe)
override;
263 bool preorder(
const IR::Member *m)
override;
264 bool preorder(
const IR::StructExpression *m)
override;
266 bool preorder(
const IR::Constant *)
override;
267 bool preorder(
const IR::BoolLiteral *)
override;
268 bool preorder(
const IR::AttribLocal *)
override { BUG(
"unconverted p4_14"); }
269 bool preorder(
const IR::Slice *)
override;
270 bool preorder(
const IR::MAU::Primitive *)
override;
271 bool preorder(
const IR::MAU::SaluRegfileRow *)
override;
272 bool preorder(
const IR::Operation::Relation *,
cstring op,
bool eq);
273 bool preorder(
const IR::Equ *r)
override {
return preorder(r,
"equ"_cs,
true); }
274 bool preorder(
const IR::Neq *r)
override {
return preorder(r,
"neq"_cs,
true); }
275 bool preorder(
const IR::Grt *r)
override {
return preorder(r,
"grt"_cs,
false); }
276 bool preorder(
const IR::Lss *r)
override {
return preorder(r,
"lss"_cs,
false); }
277 bool preorder(
const IR::Geq *r)
override {
return preorder(r,
"geq"_cs,
false); }
278 bool preorder(
const IR::Leq *r)
override {
return preorder(r,
"leq"_cs,
false); }
279 bool preorder(
const IR::Cast *)
override;
280 void postorder(
const IR::Cast *)
override;
281 bool preorder(
const IR::BFN::SignExtend *)
override;
282 bool preorder(
const IR::BFN::ReinterpretCast *)
override {
return true; }
283 void postorder(
const IR::BFN::ReinterpretCast *)
override;
284 bool preorder(
const IR::LNot *)
override {
return true; }
285 void postorder(
const IR::LNot *)
override;
286 bool preorder(
const IR::LAnd *)
override {
return true; }
287 void postorder(
const IR::LAnd *)
override;
288 bool preorder(
const IR::LOr *)
override {
return true; }
289 void postorder(
const IR::LOr *)
override;
290 bool preorder(
const IR::Mux *)
override;
291 bool preorder(
const IR::Add *)
override;
292 bool preorder(
const IR::AddSat *)
override;
293 bool preorder(
const IR::Sub *)
override;
294 bool preorder(
const IR::SubSat *)
override;
295 bool preorder(
const IR::Neg *)
override;
296 void postorder(
const IR::Neg *)
override;
297 bool preorder(
const IR::Cmpl *)
override {
return true; }
298 void postorder(
const IR::Cmpl *)
override;
299 bool preorder(
const IR::BAnd *)
override;
300 void postorder(
const IR::BAnd *)
override;
301 bool preorder(
const IR::BOr *)
override;
302 void postorder(
const IR::BOr *)
override;
303 bool preorder(
const IR::BXor *)
override;
304 void postorder(
const IR::BXor *)
override;
305 bool preorder(
const IR::Concat *)
override;
306 void postorder(
const IR::Concat *)
override;
307 bool divmod(
const IR::Operation::Binary *,
cstring op);
308 bool preorder(
const IR::Div *e)
override {
return divmod(e,
"div"_cs); }
309 bool preorder(
const IR::Mod *e)
override {
return divmod(e,
"mod"_cs); }
310 bool preorder(
const IR::Expression *e)
override {
311 error(
"%s: expression too complex for register action", e->srcInfo);
315 friend std::ostream &operator<<(std::ostream &, CreateSaluInstruction::LocalVar::use_t);
316 friend std::ostream &operator<<(std::ostream &, CreateSaluInstruction::etype_t);
317 static std::map<std::pair<cstring, cstring>, std::vector<param_t>> function_param_types;
320 explicit CreateSaluInstruction(IR::MAU::StatefulAlu *salu) : salu(salu) {
321 if (
auto spec = salu->reg->type->to<IR::Type_Specialized>())
322 regtype = spec->arguments->at(0);
324 regtype = IR::Type::Bits::get(1);
325 visitDagOnce =
false;
372class FixupStatefulAlu :
public PassManager {
392 struct return_enum_info_t {
395 const IR::MAU::SaluAction::ReturnEnumEncoding *encoding;
399 const IR::Type::Bits *pred_type;
402 FixupStatefulAlu &self;
403 bool preorder(
const IR::MAU::SaluAction *)
override;
404 bool preorder(
const IR::MAU::Action *)
override {
return false; }
405 explicit FindEncodings(FixupStatefulAlu &self) : self(self) {}
407 struct UpdateEncodings :
public Transform {
408 FixupStatefulAlu &self;
409 const IR::BFN::Pipe *preorder(IR::BFN::Pipe *p)
override {
410 if (self.encodings.empty()) prune();
413 const IR::MAU::SaluAction *preorder(IR::MAU::SaluAction *)
override;
414 const IR::Operation::Relation *preorder(IR::Operation::Relation *)
override;
415 const IR::Expression *preorder(IR::Member *)
override;
416 const IR::Expression *preorder(IR::Expression *)
override;
417 const IR::BFN::ParserRVal *postorder(IR::BFN::SavedRVal *)
override;
419 explicit UpdateEncodings(FixupStatefulAlu &self) : self(self) {}
421 struct ReplaceUpdatedEnumTypes :
public Transform {
422 FixupStatefulAlu &self;
423 const IR::Expression *postorder(IR::Expression *exp) {
424 visit(exp->type,
"type");
427 const IR::Type *preorder(IR::Type_Enum *enum_t) {
428 if (self.encodings.count(getOriginal<IR::Type_Enum>()))
return self.pred_type;
431 explicit ReplaceUpdatedEnumTypes(FixupStatefulAlu &self) : self(self) {}
438 new FindEncodings(*
this),
439 new UpdateEncodings(*
this),
440 new ReplaceUpdatedEnumTypes(*
this),
442 pred_type_size = 1 << Device::statefulAluSpec().CmpUnits.size();
443 pred_type = IR::Type::Bits::get(pred_type_size);