118 IR::BFN::Pipe *preorder(IR::BFN::Pipe *pipe)
override {
119 BUG_CHECK(pipe->headerStackInfo !=
nullptr,
120 "Running HeaderPushPop without running "
121 "CollectHeaderStackInfo first?");
122 stacks = pipe->headerStackInfo;
127 const IR::HeaderRef *to,
const IR::HeaderRef *from) {
128 for (
auto field : hdr->fields) {
129 auto dst =
new IR::Member(field->type, to, field->name);
130 auto src =
new IR::Member(field->type, from, field->name);
131 rv->push_back(
new IR::MAU::Primitive(
"modify_field"_cs, dst, src));
134 IR::Node *do_push(
const IR::HeaderRef *stack,
int count) {
135 auto &
info = stacks->at(stack->toString());
137 for (
int i =
info.size - 1; i >= count; --i)
138 copy_hdr(rv, stack->baseRef()->type,
139 new IR::HeaderStackItemRef(stack,
new IR::Constant(i)),
140 new IR::HeaderStackItemRef(stack,
new IR::Constant(i - count)));
141 auto *valid =
new IR::Member(IR::Type::Bits::get(
info.size +
info.maxpop +
info.maxpush),
143 rv->push_back(
new IR::MAU::Primitive(
144 "modify_field"_cs, MakeSlice(valid,
info.maxpop,
info.maxpop +
info.size - 1),
145 MakeSlice(valid,
info.maxpop + count,
info.maxpop +
info.size + count - 1)));
148 IR::Node *do_pop(
const IR::HeaderRef *stack,
int count) {
149 auto &
info = stacks->at(stack->toString());
151 for (
int i = count; i <
info.size; ++i)
152 copy_hdr(rv, stack->baseRef()->type,
153 new IR::HeaderStackItemRef(stack,
new IR::Constant(i - count)),
154 new IR::HeaderStackItemRef(stack,
new IR::Constant(i)));
155 auto *valid =
new IR::Member(IR::Type::Bits::get(
info.size +
info.maxpop +
info.maxpush),
157 rv->push_back(
new IR::MAU::Primitive(
158 "modify_field"_cs, MakeSlice(valid,
info.maxpop,
info.maxpop +
info.size - 1),
159 MakeSlice(valid,
info.maxpop - count,
info.maxpop +
info.size - count - 1)));
163 IR::Node *preorder(IR::MAU::Primitive *prim)
override {
164 BUG_CHECK(stacks !=
nullptr,
165 "No HeaderStackInfo; was HeaderPushPop "
166 "applied to a non-Pipe node?");
167 if (prim->name ==
"push_front")
168 return do_push(prim->operands[0]->to<IR::HeaderRef>(),
169 prim->operands[1]->to<IR::Constant>()->asInt());
170 else if (prim->name ==
"pop_front")
171 return do_pop(prim->operands[0]->to<IR::HeaderRef>(),
172 prim->operands[1]->to<IR::Constant>()->asInt());
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void info(const int kind, const char *format, const T *node, Args &&...args)
Report info messages of type kind. Requires that the node argument have source info.
Definition lib/error.h:148