Skip to content

Commit

Permalink
WIP: >64-bit arithmetic
Browse files Browse the repository at this point in the history
  • Loading branch information
mouse-mt authored and vbnogueira committed Sep 13, 2024
1 parent 9e77cde commit 2ec50a5
Show file tree
Hide file tree
Showing 18 changed files with 182 additions and 29 deletions.
16 changes: 8 additions & 8 deletions backends/dpdk/dpdkArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ bool ExpressionUnroll::preorder(const IR::Operation_Unary *u) {
} else {
un_expr = u;
}
root = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
root = new IR::PathExpression(IR::ID(refMap->newName("tmpAE")));
stmt.push_back(new IR::AssignmentStatement(root, un_expr));
decl.push_back(new IR::Declaration_Variable(root->path->name, u->type));
return false;
Expand All @@ -808,7 +808,7 @@ bool ExpressionUnroll::preorder(const IR::Operation_Binary *bin) {
if (!left_root) left_root = bin->left;
if (!right_root) right_root = bin->right;

root = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
root = new IR::PathExpression(IR::ID(refMap->newName("tmpAF")));

decl.push_back(new IR::Declaration_Variable(root->path->name, bin->type));

Expand All @@ -831,7 +831,7 @@ bool ExpressionUnroll::preorder(const IR::MethodCallExpression *m) {
else
args->push_back(new IR::Argument(root));
}
root = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
root = new IR::PathExpression(IR::ID(refMap->newName("tmpAG")));
decl.push_back(new IR::Declaration_Variable(root->path->name, m->type));
auto new_m = new IR::MethodCallExpression(m->method, args);
stmt.push_back(new IR::AssignmentStatement(root, new_m));
Expand Down Expand Up @@ -943,7 +943,7 @@ bool LogicalExpressionUnroll::preorder(const IR::Operation_Unary *u) {
un_expr = u;
}

auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmpAH")));
root = tmp;
stmt.push_back(new IR::AssignmentStatement(root, un_expr));
decl.push_back(new IR::Declaration_Variable(tmp->path->name, u->type));
Expand All @@ -967,7 +967,7 @@ bool LogicalExpressionUnroll::preorder(const IR::Operation_Binary *bin) {
bin_expr->right = right_root;
root = bin_expr;
} else {
auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmpAI")));
root = tmp;
decl.push_back(new IR::Declaration_Variable(tmp->path->name, bin->type));
IR::Operation_Binary *bin_expr;
Expand All @@ -993,7 +993,7 @@ bool LogicalExpressionUnroll::preorder(const IR::MethodCallExpression *m) {
root = m->clone();
return false;
}
auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
auto tmp = new IR::PathExpression(IR::ID(refMap->newName("tmpAJ")));
root = tmp;
decl.push_back(new IR::Declaration_Variable(tmp->path->name, m->type));
auto new_m = new IR::MethodCallExpression(m->method, args);
Expand Down Expand Up @@ -1049,7 +1049,7 @@ const IR::Node *ConvertBinaryOperationTo2Params::postorder(IR::AssignmentStateme
IR::IndexedVector<IR::StatOrDecl> code_block;
auto control = findOrigCtxt<IR::P4Control>();
auto parser = findOrigCtxt<IR::P4Parser>();
auto tmpOp1 = new IR::PathExpression(IR::ID(refMap->newName("tmp")));
auto tmpOp1 = new IR::PathExpression(IR::ID(refMap->newName("tmpAK")));
injector.collect(control, parser,
new IR::Declaration_Variable(tmpOp1->path->name, left->type));
code_block.push_back(new IR::AssignmentStatement(tmpOp1, r->left));
Expand Down Expand Up @@ -1338,7 +1338,7 @@ const IR::Node *DismantleMuxExpressions::preorder(IR::Mux *expression) {

cstring DismantleMuxExpressions::createTemporary(const IR::Type *type) {
type = type->getP4Type();
auto tmp = refMap->newName("tmp");
auto tmp = refMap->newName("tmpAL");
auto decl = new IR::Declaration_Variable(IR::ID(tmp, nullptr), type);
toInsert.push_back(decl);
return tmp;
Expand Down
2 changes: 1 addition & 1 deletion backends/dpdk/dpdkHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ bool ConvertStatementToDpdk::preorder(const IR::AssignmentStatement *a) {
auto maskMsb = tmp->value << (consOrgBitwidth - 1);
// Move param to metadata as DPDK expects it to be in metadata
BUG_CHECK(metadataStruct, "Metadata structure missing unexpectedly!");
IR::ID src1(refmap->newName("tmp"));
IR::ID src1(refmap->newName("tmpAM"));
metadataStruct->fields.push_back(new IR::StructField(src1, src2Op->type));
auto src1Member = new IR::Member(new IR::PathExpression("m"), src1);
add_instr(
Expand Down
24 changes: 22 additions & 2 deletions backends/ebpf/codeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ bool CodeGenInspector::preorder(const IR::Cast *c) {
widthCheck(c);
int prec = expressionPrecedence;
bool useParens = prec > c->getPrecedence();
std::cout << "CGI::preorder(IR::Cast), " << (void *)c << ", destType "
<< c->destType->toString() << std::endl;
if (useParens) builder->append("(");
builder->append("(");
auto et = EBPFTypeFactory::instance->create(c->destType);
Expand Down Expand Up @@ -352,15 +354,29 @@ void CodeGenInspector::emitAssignStatement(const IR::Type *ltype, const IR::Expr
memcpy = !EBPFScalarType::generatesScalar(width);
}

builder->emitIndent();
if (lexpr == nullptr)
builder->appendFormat("/* lexpr = nil, lpath %s */", lpath);
else
builder->appendFormat("/* lexpr = %s */", lexpr->toString());
builder->newline();
builder->emitIndent();
builder->appendFormat("/* rexpr = %s */", rexpr->toString());
builder->newline();
builder->emitIndent();
if (memcpy) {
builder->append("__builtin_memcpy(&");
builder->append("__builtin_memcpy/*G*/(&");
if (lexpr != nullptr) {
visit(lexpr);
} else {
builder->append(lpath);
}
builder->append(", &");
builder->append(", ");
auto rtype = EBPFTypeFactory::instance->create(typeMap->getType(rexpr));
if (rtype->is<EBPFScalarType>() && rtype->is_array())
builder->append("& /* no */");
else
builder->append("/* yes */");
if (rexpr->is<IR::Constant>()) {
builder->appendFormat("(u8[%u])", scalar->bytesRequired());
}
Expand Down Expand Up @@ -455,6 +471,7 @@ bool CodeGenInspector::preorder(const IR::MethodCallStatement *s) {
}

void CodeGenInspector::widthCheck(const IR::Node *node) const {
#if 0
// This is a temporary solution.
// Rather than generate incorrect results, we reject programs that
// do not perform arithmetic on machine-supported widths.
Expand All @@ -472,6 +489,9 @@ void CodeGenInspector::widthCheck(const IR::Node *node) const {
}
::P4::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET, "%1%: Computations on %2% bits not supported",
node, tb->size);
#else
(void)node;
#endif
}

void CodeGenInspector::emitAndConvertByteOrder(const IR::Expression *expr, cstring byte_order) {
Expand Down
2 changes: 1 addition & 1 deletion backends/ebpf/ebpfDeparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ void DeparserHdrEmitTranslator::emitField(CodeBuilder *builder, cstring field,
builder->endOfStatement(true);
msgStr = absl::StrFormat("Deparser: emitting field %s=0x%%llx (%u bits)", field,
widthToEmit);
builder->target->emitTraceMessage(builder, msgStr.c_str(), 1, "tmp");
builder->target->emitTraceMessage(builder, msgStr.c_str(), 1, "tmpAC");
builder->blockEnd(true);
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion backends/ebpf/ebpfType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ EBPFType *EBPFTypeFactory::create(const IR::Type *type) {
// Implement error type as scalar of width 8 bits
result = new EBPFScalarType(IR::Type_Bits::get(8, false));
} else {
::P4::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET, "Type %1% not supported", type);
::P4::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET, "Type %1% not supported [factory create]",
type);
}

return result;
Expand Down
3 changes: 3 additions & 0 deletions backends/ebpf/ebpfType.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class EBPFType : public EBPFObject {
virtual void declareArray(CodeBuilder * /*builder*/, cstring /*id*/, unsigned /*size*/) {
BUG("%1%: unsupported array", type);
}
virtual bool is_array() { return (false); }

DECLARE_TYPEINFO(EBPFType, EBPFObject);
};
Expand Down Expand Up @@ -121,6 +122,8 @@ class EBPFScalarType : public EBPFType, public IHasWidth {
unsigned implementationWidthInBits() const override { return bytesRequired() * 8; }
// True if this width is small enough to store in a machine scalar
static bool generatesScalar(unsigned width) { return width <= 64; }
// XXX Should we be using generatesScalar instead of defining another method?
virtual bool is_array() override { return (width > 64); }

DECLARE_TYPEINFO(EBPFScalarType, EBPFType, IHasWidth);
};
Expand Down
106 changes: 104 additions & 2 deletions backends/tc/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,106 @@ const cstring pnaParserMeta = "pna_main_parser_input_metadata_t"_cs;
const cstring pnaInputMeta = "pna_main_input_metadata_t"_cs;
const cstring pnaOutputMeta = "pna_main_output_metadata_t"_cs;

const IR::Node *FIXUP_CASTS::preorder(IR::Statement *s) {
CONTAINER *c;

std::cout << "cast fixup: preorder: " << (void *)s << '\n' << s->toString() << std::endl;
c = new CONTAINER;
c->temps = 0;
c->s = s;
c->link = contain;
contain = c;
return (s);
}

const IR::Node *FIXUP_CASTS::postorder(IR::Statement *s) {
CONTAINER *c;
DECLLIST *temps;
DECLLIST *t;
IR::BlockStatement *b;

std::cout << "cast fixup: postorder: " << (void *)s << '\n' << s->toString() << std::endl;
c = contain;
if (c->s != s) abort();
contain = c->link;
temps = c->temps;
c->temps = 0;
delete c;
if (!temps) return (s);
std::cout << "Declarations:";
for (t = temps; t; t = t->link) std::cout << " " << t->decl->toString();
std::cout << std::endl;
b = new IR::BlockStatement();
for (t = temps; t; t = t->link) b->append(t->decl);
b->append(s);
return (b);
}

static void save_temp(TC::CONTAINER *c, IR::Declaration *d) {
DECLLIST *dl;

dl = new DECLLIST;
dl->decl = d;
dl->link = c->temps;
c->temps = dl;
}

/*
* The dance for IR::Type_Type is because I see such coming back from
* typemap->getType(). I don't know why and I don't know what it
* means; I hope someone who does know can fix up anything necessary.
*/
const IR::Node *FIXUP_CASTS::postorder(IR::Cast *e) {
CONTAINER *c;

if (!EBPF::EBPFTypeFactory::instance) abort();
std::cout << "cast fixup: cast expression: " << e->toString() << std::endl;
std::cout << "Contained in:";
for (c = contain; c; c = c->link) std::cout << ' ' << (void *)c->s;
std::cout << std::endl;
const IR::Type *argtype;
argtype = typemap->getType(e->expr, true);
if (argtype->is<IR::Type_Type>()) argtype = argtype->to<const IR::Type_Type>()->type;
std::cout << "Arg type: " << argtype->toString() << std::endl;
const IR::Type *casttype;
casttype = typemap->getType(e->destType, true);
if (casttype->is<IR::Type_Type>()) casttype = casttype->to<const IR::Type_Type>()->type;
std::cout << "Cast-to type: " << casttype->toString() << std::endl;
auto aet = EBPF::EBPFTypeFactory::instance->create(argtype);
std::cout << "Arg EBPF type: " << (void *)aet << std::endl;
std::cout << " (" << aet->type->toString() << ")" << std::endl;
auto cet = EBPF::EBPFTypeFactory::instance->create(casttype);
std::cout << "Cast-to EBPF type: " << (void *)cet << std::endl;
std::cout << " (" << cet->type->toString() << ")" << std::endl;
std::cout << "Arg is scalar: " << (aet->is<EBPF::EBPFScalarType>() ? "YES" : "NO")
<< "; result is scalar: " << (cet->is<EBPF::EBPFScalarType>() ? "YES" : "NO")
<< std::endl;
if (!aet->is<EBPF::EBPFScalarType>() || !cet->is<EBPF::EBPFScalarType>()) return (e);
auto aw = aet->to<EBPF::EBPFScalarType>()->implementationWidthInBits();
auto cw = cet->to<EBPF::EBPFScalarType>()->implementationWidthInBits();
std::cout << "Arg width: " << aw
<< ", scalar: " << (EBPF::EBPFScalarType::generatesScalar(aw) ? "YES" : "NO") << '\n';
std::cout << "Result width: " << cw
<< ", scalar: " << (EBPF::EBPFScalarType::generatesScalar(cw) ? "YES" : "NO")
<< std::endl;
if (EBPF::EBPFScalarType::generatesScalar(aw) && EBPF::EBPFScalarType::generatesScalar(cw))
return (e);
auto sn = refmap->newName("cast_src");
auto dn = refmap->newName("cast_dst");
std::cout << "sn=" << sn << ", dn=" << dn << std::endl;
auto sd = new IR::Declaration_Variable(IR::ID(sn, nullptr), argtype);
auto dd = new IR::Declaration_Variable(IR::ID(dn, nullptr), casttype);
std::cout << "Src declaration: " << sd->toString() << std::endl;
std::cout << "Dst declaration: " << dd->toString() << std::endl;
save_temp(contain, sd);
save_temp(contain, dd);
auto px = new IR::PathExpression(dd->getName());
std::cout << "Cast expression: " << (void *)e << ", " << e->toString() << std::endl;
std::cout << "Replacement expression: " << (void *)px << ", " << px->toString() << std::endl;
return (px);
// return(e);
}

bool Backend::process() {
CHECK_NULL(toplevel);
if (toplevel->getMain() == nullptr) {
Expand All @@ -52,9 +152,11 @@ bool Backend::process() {
parseTCAnno = new ParseTCAnnotations();
tcIR = new ConvertToBackendIR(toplevel, pipeline, refMap, typeMap, options);
genIJ = new IntrospectionGenerator(pipeline, refMap, typeMap);
EBPF::EBPFTypeFactory::createFactory(typeMapEBPF);
PassManager backEnd = {};
backEnd.addPasses({parseTCAnno, new P4::ClearTypeMap(typeMap),
new P4::TypeChecking(refMap, typeMap, true), tcIR, genIJ});
new P4::TypeChecking(refMap, typeMap, true), tcIR, genIJ,
new FIXUP_CASTS(refMap, typeMap)});
backEnd.addDebugHook(hook, true);
toplevel->getProgram()->apply(backEnd);
if (::P4::errorCount() > 0) return false;
Expand Down Expand Up @@ -101,7 +203,7 @@ bool Backend::ebpfCodeGen(P4::ReferenceMap *refMapEBPF, P4::TypeMap *typeMapEBPF
main->apply(*parsePnaArch);
program = top->getProgram();

EBPF::EBPFTypeFactory::createFactory(typeMapEBPF);
// EBPF::EBPFTypeFactory::createFactory(typeMapEBPF);
auto convertToEbpf = new ConvertToEbpfPNA(ebpfOption, refMapEBPF, typeMapEBPF, tcIR);
PassManager toEBPF = {
new P4::DiscoverStructure(&structure),
Expand Down
27 changes: 27 additions & 0 deletions backends/tc/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@ extern cstring PnaMainOutputMetaFields[TC::MAX_PNA_OUTPUT_META];

class PNAEbpfGenerator;

typedef struct decllist DECLLIST;
struct decllist {
DECLLIST *link;
IR::Declaration *decl;
};

typedef struct container CONTAINER;
struct container {
CONTAINER *link;
DECLLIST *temps;
IR::Statement *s;
};

class FIXUP_CASTS : public Transform {
private:
CONTAINER *contain;
P4::ReferenceMap *refmap;
P4::TypeMap *typemap;
const IR::Node *preorder(IR::Statement *) override;
const IR::Node *postorder(IR::Statement *) override;
const IR::Node *postorder(IR::Cast *) override;

public:
explicit FIXUP_CASTS(P4::ReferenceMap *rm, P4::TypeMap *tm)
: contain(0), refmap(rm), typemap(tm){};
};

/**
* Backend code generation from midend IR
*/
Expand Down
6 changes: 3 additions & 3 deletions backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ void PnaStateTranslationVisitor::compileExtractField(const IR::Expression *expr,
unsigned shift = loadSize - alignment - widthToExtract;
builder->emitIndent();
if (noEndiannessConversion) {
builder->appendFormat("__builtin_memcpy(&");
builder->appendFormat("__builtin_memcpy/*A*/(&");
visit(expr);
builder->appendFormat(".%s, %s + BYTES(%s), %d)", fieldName,
program->packetStartVar.c_str(), program->offsetVar.c_str(),
Expand Down Expand Up @@ -1881,7 +1881,7 @@ void ControlBodyTranslatorPNA::processApply(const P4::ApplyMethod *method) {

builder->emitIndent();
if (memcpy) {
builder->appendFormat("__builtin_memcpy(&(%s.%s[0]), &(", keyname.c_str(),
builder->appendFormat("__builtin_memcpy/*B*/(&(%s.%s[0]), &(", keyname.c_str(),
fieldName.c_str());
table->codeGen->visit(c->expression);
builder->appendFormat("[0]), %d)", scalar->bytesRequired());
Expand Down Expand Up @@ -2269,7 +2269,7 @@ void DeparserHdrEmitTranslatorPNA::emitField(EBPF::CodeBuilder *builder, cstring
builder->endOfStatement(true);
msgStr = absl::StrFormat("Deparser: emitting field %s=0x%%llx (%u bits)", field,
widthToEmit);
builder->target->emitTraceMessage(builder, msgStr.c_str(), 1, "tmp");
builder->target->emitTraceMessage(builder, msgStr.c_str(), 1, "tmpAD");
builder->blockEnd(true);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions backends/tc/tcExterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void EBPFRegisterPNA::emitRegisterRead(EBPF::CodeBuilder *builder, const P4::Ext
builder->appendLine("ext_val = *ext_val_ptr;");
if (leftExpression != nullptr) {
builder->emitIndent();
builder->append("__builtin_memcpy(&");
builder->append("__builtin_memcpy/*C*/(&");
translator->visit(leftExpression);
builder->append(", ext_val.out_params, sizeof(");
this->valueType->declare(builder, cstring::empty, false);
Expand All @@ -73,7 +73,7 @@ void EBPFRegisterPNA::emitRegisterWrite(EBPF::CodeBuilder *builder, const P4::Ex

builder->newline();
builder->emitIndent();
builder->append("__builtin_memcpy(ext_val.out_params, &");
builder->append("__builtin_memcpy/*D*/(ext_val.out_params, &");
translator->visit(value);
builder->append(", sizeof(");
this->valueType->declare(builder, cstring::empty, false);
Expand Down
2 changes: 1 addition & 1 deletion backends/ubpf/ubpfControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ bool UBPFControlBodyTranslator::emitRegisterRead(const IR::AssignmentStatement *
pRegister->emitKeyInstance(builder, method);

auto etype = UBPFTypeFactory::instance->create(pRegister->keyType);
auto tmp = control->program->refMap->newName("tmp");
auto tmp = control->program->refMap->newName("tmpAA");
etype->declare(builder, tmp, true);
builder->endOfStatement(true);

Expand Down
Loading

0 comments on commit 2ec50a5

Please sign in to comment.