@@ -64,55 +64,72 @@ const IR::Expression* DoExpandLookahead::expand(
64
64
}
65
65
}
66
66
67
- const IR::Node* DoExpandLookahead::postorder (IR::AssignmentStatement* statement) {
68
- if (!statement->right ->is <IR::MethodCallExpression>())
69
- return statement;
70
-
71
- auto mce = statement->right ->to <IR::MethodCallExpression>();
72
- auto mi = MethodInstance::resolve (mce, refMap, typeMap);
67
+ DoExpandLookahead::ExpansionInfo*
68
+ DoExpandLookahead::convertLookahead (const IR::MethodCallExpression* expression) {
69
+ if (expression == nullptr )
70
+ return nullptr ;
71
+ auto mi = MethodInstance::resolve (expression, refMap, typeMap);
73
72
if (!mi->is <P4::ExternMethod>())
74
- return statement ;
73
+ return nullptr ;
75
74
auto em = mi->to <P4::ExternMethod>();
76
75
if (em->originalExternType ->name != P4CoreLibrary::instance.packetIn .name ||
77
76
em->method ->name != P4CoreLibrary::instance.packetIn .lookahead .name )
78
- return statement ;
77
+ return nullptr ;
79
78
80
79
// this is a call to packet_in.lookahead.
81
- BUG_CHECK (mce ->typeArguments ->size () == 1 ,
80
+ BUG_CHECK (expression ->typeArguments ->size () == 1 ,
82
81
" Expected 1 type parameter for %1%" , em->method );
83
- auto targ = mce ->typeArguments ->at (0 );
82
+ auto targ = expression ->typeArguments ->at (0 );
84
83
auto typearg = typeMap->getTypeType (targ, true );
85
84
if (!typearg->is <IR::Type_StructLike>() && !typearg->is <IR::Type_Tuple>())
86
- return statement ;
85
+ return nullptr ;
87
86
88
- int width = typearg->width_bits ();
89
- if (width <= 0 ) {
90
- ::error (" %1%: type argument of %2% must be a fixed-width type" ,
91
- targ, P4CoreLibrary::instance.packetIn.lookahead.name);
92
- return statement;
93
- }
87
+ int width = typeMap->minWidthBits (typearg, expression);
88
+ if (width < 0 )
89
+ return nullptr ;
94
90
95
91
auto bittype = IR::Type_Bits::get (width);
96
92
auto name = refMap->newName (" tmp" );
97
93
auto decl = new IR::Declaration_Variable (IR::ID (name), bittype, nullptr );
98
94
newDecls.push_back (decl);
99
95
100
- auto result = new IR::BlockStatement;
101
96
auto ta = new IR::Vector<IR::Type>();
102
97
ta->push_back (bittype);
103
- auto mc = new IR::MethodCallExpression (mce->srcInfo , mce->method ->clone (), ta, mce->arguments );
98
+ auto mc = new IR::MethodCallExpression (
99
+ expression->srcInfo , expression->method ->clone (), ta, expression->arguments );
104
100
auto pathe = new IR::PathExpression (name);
105
- auto lookupCall = new IR::AssignmentStatement (statement->srcInfo , pathe, mc);
106
- result->push_back (lookupCall);
101
+ auto lookupCall = new IR::AssignmentStatement (expression->srcInfo , pathe, mc);
102
+ auto result = new ExpansionInfo;
103
+ result->statement = lookupCall;
104
+ result->width = (unsigned )width;
105
+ result->origType = typearg;
106
+ result->tmp = pathe;
107
+ return result;
108
+ }
109
+
110
+ const IR::Node* DoExpandLookahead::postorder (IR::MethodCallStatement* statement) {
111
+ auto ei = convertLookahead (statement->methodCall );
112
+ if (ei == nullptr )
113
+ return statement;
114
+ return ei->statement ;
115
+ }
116
+
117
+ const IR::Node* DoExpandLookahead::postorder (IR::AssignmentStatement* statement) {
118
+ if (!statement->right ->is <IR::MethodCallExpression>())
119
+ return statement;
107
120
108
- unsigned offset = width;
109
- expandSetValid (statement->left ->clone (), typearg, &result->components );
110
- auto init = expand (pathe->clone (), typearg, &offset);
121
+ auto ei = convertLookahead (statement->right ->to <IR::MethodCallExpression>());
122
+ if (ei == nullptr )
123
+ return statement;
124
+ auto result = new IR::BlockStatement;
125
+ result->push_back (ei->statement );
126
+
127
+ expandSetValid (statement->left ->clone (), ei->origType , &result->components );
128
+ auto init = expand (ei->tmp ->clone (), ei->origType , &ei->width );
111
129
if (init == nullptr )
112
130
return statement;
113
131
auto assignment = new IR::AssignmentStatement (statement->srcInfo , statement->left , init);
114
132
result->push_back (assignment);
115
-
116
133
return result;
117
134
}
118
135
0 commit comments