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