-
Notifications
You must be signed in to change notification settings - Fork 0
/
metermap.cpp
93 lines (80 loc) · 3.1 KB
/
metermap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
Copyright 2013-present Barefoot Networks, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "metermap.h"
namespace BMV2 {
/**
* @returns direct meter information from the direct meter map
*/
DirectMeterMap::DirectMeterInfo* DirectMeterMap::createInfo(const IR::IDeclaration* meter) {
auto prev = ::get(directMeter, meter);
BUG_CHECK(prev == nullptr, "Already created");
auto result = new DirectMeterMap::DirectMeterInfo();
directMeter.emplace(meter, result);
return result;
}
DirectMeterMap::DirectMeterInfo* DirectMeterMap::getInfo(const IR::IDeclaration* meter) {
return ::get(directMeter, meter);
}
/**
* Set the table that a direct meter is attached to.
*/
void DirectMeterMap::setTable(const IR::IDeclaration* meter, const IR::P4Table* table) {
auto info = getInfo(meter);
CHECK_NULL(info);
if (info->table != nullptr)
::error("%1%: Direct meters cannot be attached to multiple tables %2% and %3%",
meter, table, info->table);
info->table = table;
}
/**
* Helper function to check if two expressions are syntactically identical
*/
static bool checkSame(const IR::Expression* expr0, const IR::Expression* expr1) {
if (expr0->node_type_name() != expr1->node_type_name())
return false;
if (auto pe0 = expr0->to<IR::PathExpression>()) {
auto pe1 = expr1->to<IR::PathExpression>();
return pe0->path->name == pe1->path->name &&
pe0->path->absolute == pe1->path->absolute;
} else if (auto mem0 = expr0->to<IR::Member>()) {
auto mem1 = expr1->to<IR::Member>();
return checkSame(mem0->expr, mem1->expr) && mem0->member == mem1->member;
}
BUG("%1%: unexpected expression for meter destination", expr0);
}
/**
* Set the destination that a meter is attached to??
*/
void DirectMeterMap::setDestination(const IR::IDeclaration* meter,
const IR::Expression* destination) {
auto info = getInfo(meter);
if (info == nullptr)
info = createInfo(meter);
if (info->destinationField == nullptr) {
info->destinationField = destination;
} else {
bool same = checkSame(destination, info->destinationField);
if (!same)
::error("On this target all meter operations must write to the same destination "
"but %1% and %2% are different", destination, info->destinationField);
}
}
/**
* Set the size of the table that a meter is attached to.
*/
void DirectMeterMap::setSize(const IR::IDeclaration* meter, unsigned size) {
auto info = getInfo(meter);
CHECK_NULL(info);
info->tableSize = size;
}
} // namespace BMV2