@@ -49,7 +49,7 @@ const IR::Node* LowerExpressions::postorder(IR::Neg* expression) {
49
49
auto sub = new IR::Sub (expression->srcInfo , zero, expression->expr );
50
50
typeMap->setType (zero, type);
51
51
typeMap->setType (sub, type);
52
- LOG1 (" Replaced " << expression << " with " << sub);
52
+ LOG3 (" Replaced " << expression << " with " << sub);
53
53
return sub;
54
54
}
55
55
@@ -61,14 +61,14 @@ const IR::Node* LowerExpressions::postorder(IR::Cast* expression) {
61
61
auto zero = new IR::Constant (srcType, 0 );
62
62
auto cmp = new IR::Equ (expression->srcInfo , expression->expr , zero);
63
63
typeMap->setType (cmp, destType);
64
- LOG1 (" Replaced " << expression << " with " << cmp);
64
+ LOG3 (" Replaced " << expression << " with " << cmp);
65
65
return cmp;
66
66
} else if (destType->is <IR::Type_Bits>() && srcType->is <IR::Type_Boolean>()) {
67
67
auto mux = new IR::Mux (expression->srcInfo , expression->expr ,
68
68
new IR::Constant (destType, 1 ),
69
69
new IR::Constant (destType, 0 ));
70
70
typeMap->setType (mux, destType);
71
- LOG1 (" Replaced " << expression << " with " << mux);
71
+ LOG3 (" Replaced " << expression << " with " << mux);
72
72
return mux;
73
73
}
74
74
// This may be a new expression
@@ -93,7 +93,7 @@ const IR::Node* LowerExpressions::postorder(IR::Slice* expression) {
93
93
auto type = IR::Type_Bits::get (h - l + 1 );
94
94
auto result = new IR::Cast (expression->srcInfo , type, sh);
95
95
typeMap->setType (result, type);
96
- LOG1 (" Replaced " << expression << " with " << result);
96
+ LOG3 (" Replaced " << expression << " with " << result);
97
97
return result;
98
98
}
99
99
@@ -121,7 +121,7 @@ const IR::Node* LowerExpressions::postorder(IR::Concat* expression) {
121
121
typeMap->setType (result, resulttype);
122
122
typeMap->setType (sh, resulttype);
123
123
typeMap->setType (and0, resulttype);
124
- LOG1 (" Replaced " << expression << " with " << result);
124
+ LOG3 (" Replaced " << expression << " with " << result);
125
125
return result;
126
126
}
127
127
@@ -347,4 +347,51 @@ const IR::Node* FixupChecksum::preorder(IR::P4Control* control) {
347
347
return control;
348
348
}
349
349
350
+ // //////////////////////////////////////////////////////////////////////////////////
351
+
352
+ namespace {
353
+
354
+ // Detect whether a Select expression is too complicated for BMv2
355
+ class ComplexExpression : public Inspector {
356
+ public:
357
+ bool isComplex = false ;
358
+ ComplexExpression () { setName (" ComplexExpression" ); }
359
+
360
+ void postorder (const IR::PathExpression*) override {}
361
+ void postorder (const IR::Member*) override {}
362
+ void postorder (const IR::Literal*) override {}
363
+ // all other expressions are complex
364
+ void postorder (const IR::Expression*) override { isComplex = true ; }
365
+ };
366
+
367
+ } // namespace
368
+
369
+ const IR::Node*
370
+ RemoveExpressionsFromSelects::postorder (IR::SelectExpression* expression) {
371
+ bool changes = true ;
372
+ auto vec = new IR::Vector<IR::Expression>();
373
+ for (auto e : *expression->select ->components ) {
374
+ ComplexExpression ce;
375
+ (void )e->apply (ce);
376
+ if (ce.isComplex ) {
377
+ changes = true ;
378
+ auto type = typeMap->getType (e, true )->getP4Type ();
379
+ auto name = refMap->newName (" tmp" );
380
+ auto decl = new IR::Declaration_Variable (Util::SourceInfo (), IR::ID (name),
381
+ IR::Annotations::empty, type, nullptr );
382
+ newDecls.push_back (decl);
383
+ auto assign = new IR::AssignmentStatement (
384
+ Util::SourceInfo (), new IR::PathExpression (name), e);
385
+ assignments.push_back (assign);
386
+ vec->push_back (new IR::PathExpression (name));
387
+ } else {
388
+ vec->push_back (e);
389
+ }
390
+ }
391
+
392
+ if (changes)
393
+ expression->select = new IR::ListExpression (expression->select ->srcInfo , vec);
394
+ return expression;
395
+ }
396
+
350
397
} // namespace BMV2
0 commit comments