google / cairn

Apache License 2.0
3 stars 3 forks source link

Generate our version of "toP4" #10

Open XiangyuG opened 7 months ago

XiangyuG commented 7 months ago

A lot of passes involve new IR designs which are not supported by the current toP4.cpp and toP4.h in the frontend. Our current solution is to migrate toP4 files to toCAIRN in our own directory so that we can maintain it without relying on the p4c repo.

qobilidop commented 7 months ago

As we discussed in our meeting, I feel the p4c DPDK backend could be a good reference here. I've taken a closer look at their code and taken some notes.

At the end of their backend passes, the whole program is transformed to an IR::DpdkAsmProgram:

https://github.com/p4lang/p4c/blob/e9a1c4b814d038871f78d6e784a0198a17cc79d7/backends/dpdk/backend.cpp#L133 https://github.com/p4lang/p4c/blob/e9a1c4b814d038871f78d6e784a0198a17cc79d7/backends/dpdk/backend.cpp#L153

dpdk_program = convertToDpdk->getDpdkProgram();
...
dpdk_program = dpdk_program->apply(post_code_gen)->to<IR::DpdkAsmProgram>();

This IR::DpdkAsmProgram is defined in dpdk.def:

https://github.com/p4lang/p4c/blob/e9a1c4b814d038871f78d6e784a0198a17cc79d7/backends/dpdk/dpdk.def#L98-L110

// Toplevel Assembly representation
class DpdkAsmProgram {
    inline IndexedVector<DpdkHeaderType> headerType;
    inline IndexedVector<DpdkStructType> structType;
    inline IndexedVector<DpdkExternDeclaration> externDeclarations;
    inline IndexedVector<DpdkAction> actions;
    inline IndexedVector<DpdkTable> tables;
    inline IndexedVector<DpdkSelector> selectors;
    inline IndexedVector<DpdkLearner> learners;
    inline IndexedVector<DpdkAsmStatement> statements;
    inline IndexedVector<DpdkDeclaration> globals;
    std::ostream& toSpec(std::ostream& out) const;
}

Then this IR::DpdkAsmProgram is printed out in DpdkBackend::codegen using its toSpec method:

https://github.com/p4lang/p4c/blob/e9a1c4b814d038871f78d6e784a0198a17cc79d7/backends/dpdk/backend.cpp#L156

void DpdkBackend::codegen(std::ostream &out) const { dpdk_program->toSpec(out) << std::endl; }

toSpec is implemented in https://github.com/p4lang/p4c/blob/main/backends/dpdk/spec.cpp.

Does this approach work for us at a high level? I have some questions to further discuss:

  1. I think one key strategy p4c DPDK backend adopts is to define a complete backend IR for the whole program (IR::DpdkAsmProgram) and transform a source P4 program to this backend IR completely before codegen.
  2. This approach probably won't work if we want to progressively transform p4c frontend/midend IR to our backend IR in multiple steps, and test intermediate transformation results.
  3. Is mixing 2 IRs even possible with p4c's current infra? I've taken a brief look at other p4c backends but haven't reached any concrete conclusion yet. Other p4c backends with an IR def file for reference:
    1. https://github.com/p4lang/p4c/blob/main/backends/bmv2/bmv2.def
    2. https://github.com/p4lang/p4c/blob/main/backends/p4tools/p4tools.def
    3. https://github.com/p4lang/p4c/blob/main/backends/tc/tc.def