Skip to content

Commit

Permalink
Address review
Browse files Browse the repository at this point in the history
  • Loading branch information
tatry committed Apr 22, 2022
1 parent e5de51a commit 4c6fad9
Showing 1 changed file with 40 additions and 49 deletions.
89 changes: 40 additions & 49 deletions backends/ebpf/ebpfTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -894,13 +894,16 @@ EBPFValueSet::EBPFValueSet(const EBPFProgram* program, const IR::P4ValueSet* p4v
}

// validate type
if (pvs->elementType->is<IR::Type_Bits>() || pvs->elementType->is<IR::Type_Tuple>()) {
auto elemType = program->typeMap->getType(pvs->elementType, true);
if (elemType->is<IR::Type_Type>())
elemType = elemType->to<IR::Type_Type>()->type;

if (elemType->is<IR::Type_Bits>() || elemType->is<IR::Type_Tuple>()) {
// no restrictions
} else if (pvs->elementType->is<IR::Type_Name>()) {
auto type = pvs->elementType->to<IR::Type_Name>();
keyTypeName = type->path->name.name;
} else if (auto tn = elemType->to<IR::Type_Name>()) {
keyTypeName = tn->path->name.name;

auto decl = program->refMap->getDeclaration(type->path, true);
auto decl = program->refMap->getDeclaration(tn->path, true);
if (decl->is<IR::Type_Header>()) {
::warning("Header type may contain additional shadow data: %1%", pvs->elementType);
::warning("Header defined here: %1%", decl);
Expand All @@ -919,9 +922,12 @@ EBPFValueSet::EBPFValueSet(const EBPFProgram* program, const IR::P4ValueSet* p4v
}

void EBPFValueSet::emitTypes(CodeBuilder* builder) {
if (pvs->elementType->is<IR::Type_Name>()) {
auto type = pvs->elementType->to<IR::Type_Name>();
auto decl = program->refMap->getDeclaration(type->path, true);
auto elemType = program->typeMap->getType(pvs->elementType, true);
if (elemType->is<IR::Type_Type>())
elemType = elemType->to<IR::Type_Type>()->type;

if (auto tn = elemType->to<IR::Type_Name>()) {
auto decl = program->refMap->getDeclaration(tn->path, true);
auto tsl = decl->to<IR::Type_StructLike>();
CHECK_NULL(tsl);
for (auto field : tsl->fields) {
Expand All @@ -942,13 +948,11 @@ void EBPFValueSet::emitTypes(CodeBuilder* builder) {
builder->endOfStatement(true);
};

if (pvs->elementType->is<IR::Type_Bits>()) {
auto type = pvs->elementType->to<IR::Type_Bits>();
if (auto tb = elemType->to<IR::Type_Bits>()) {
cstring name = "field0";
fieldEmitter(type, name);
fieldNames.emplace_back(std::make_pair(name, type));
} else if (pvs->elementType->is<IR::Type_Tuple>()) {
auto tuple = pvs->elementType->to<IR::Type_Tuple>();
fieldEmitter(tb, name);
fieldNames.emplace_back(std::make_pair(name, tb));
} else if (auto tuple = elemType->to<IR::Type_Tuple>()) {
int i = 0;
for (auto field : tuple->components) {
cstring name = Util::printf_format("field%d", i++);
Expand Down Expand Up @@ -978,19 +982,33 @@ void EBPFValueSet::emitKeyInitializer(CodeBuilder* builder,
}
keyVarName = varName;
builder->emitIndent();
builder->appendFormat("%s %s = ", keyTypeName.c_str(), keyVarName.c_str());
builder->blockStart();
builder->appendFormat("%s %s = {0}", keyTypeName.c_str(), keyVarName.c_str());
builder->endOfStatement(true);

// initialize small fields up to 64 bits
for (unsigned int i = 0; i < fieldNames.size(); i++) {
bool useMemcpy = true;
if (fieldNames.at(i).second->is<IR::Type_Bits>()) {
int width = fieldNames.at(i).second->to<IR::Type_Bits>()->width_bits();
if (width > 64)
if (fieldNames.at(i).second->to<IR::Type_Bits>()->width_bits() <= 64)
useMemcpy = false;
}
builder->emitIndent();

auto keyExpr = expression->select->components.at(i);
if (useMemcpy) {
if (keyExpr->is<IR::Mask>()) {
::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"%1%: mask not supported for fields larger than 64 bits within value_set",
keyExpr);
continue;
}

builder->emitIndent();
builder->appendFormat(".%s = ", fieldNames.at(i).first);
auto keyExpr = expression->select->components.at(i);
cstring dst = Util::printf_format("%s.%s", keyVarName.c_str(),
fieldNames.at(i).first.c_str());
builder->appendFormat("__builtin_memcpy(&%s, &(", dst.c_str());
codeGen->visit(keyExpr);
builder->appendFormat("), sizeof(%s))", dst.c_str());
} else {
builder->appendFormat("%s.%s = ", keyVarName.c_str(), fieldNames.at(i).first.c_str());
if (auto mask = keyExpr->to<IR::Mask>()) {
builder->append("((");
codeGen->visit(mask->left);
Expand All @@ -1000,35 +1018,8 @@ void EBPFValueSet::emitKeyInitializer(CodeBuilder* builder,
} else {
codeGen->visit(keyExpr);
}
builder->appendLine(",");
}
}

builder->blockEnd(false);
builder->endOfStatement(true);

// init other bigger fields
for (unsigned int i = 0; i < fieldNames.size(); i++) {
if (fieldNames.at(i).second->is<IR::Type_Bits>()) {
int width = fieldNames.at(i).second->to<IR::Type_Bits>()->width_bits();
if (width <= 64)
continue;
}

auto keyExpr = expression->select->components.at(i);
if (keyExpr->is<IR::Mask>()) {
::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"%1%: mask not supported for fields larger than 64 bits within value_set",
keyExpr);
continue;
}

builder->emitIndent();
cstring dst = Util::printf_format("%s.%s", keyVarName.c_str(),
fieldNames.at(i).first.c_str());
builder->appendFormat("__builtin_memcpy(&%s, &(", dst.c_str());
codeGen->visit(keyExpr);
builder->appendFormat("), sizeof(%s))", dst.c_str());
builder->endOfStatement(true);
}
}
Expand Down

0 comments on commit 4c6fad9

Please sign in to comment.