p4c icon indicating copy to clipboard operation
p4c copied to clipboard

Make don't care args action-local when used in actions

Open kfcripps opened this issue 1 year ago • 6 comments

It may be easier for some passes to process action-locals that are actually action-local variables instead of control-local variables in the IR. Also note that we already do this in the DontcareArgs pass for functions, but not actions for some reason:

    const IR::Node *postorder(IR::Function *function) override {
        IR::IndexedVector<IR::StatOrDecl> body;
        for (auto d : toAdd) body.push_back(d);
        body.append(function->body->components);
        function->body = new IR::BlockStatement(function->body->srcInfo, body);
        toAdd.clear();
        return function;
    }

On main branch, the output of --top4 RemoveDontcareArgs for the attached test is:

struct S {
    bit<64> f;
}

control C(inout S s) {
    bit<64> arg;
    @name("d") action d_0(@name("b") out bit<64> b_0) {
        b_0 = 64w4;
    }
    @name("foo") action foo_0() {
        d_0(arg);
    }
    @name("t") table t_0 {
        actions = {
            foo_0();
        }
        default_action = foo_0();
    }
    apply {
        t_0.apply();
    }
}

control proto(inout S s);
package top(proto p);
top(C()) main;

and on this branch:

struct S {
    bit<64> f;
}

control C(inout S s) {
    @name("d") action d_0(@name("b") out bit<64> b_0) {
        b_0 = 64w4;
    }
    @name("foo") action foo_0() {
        bit<64> arg;
        d_0(arg);
    }
    @name("t") table t_0 {
        actions = {
            foo_0();
        }
        default_action = foo_0();
    }
    apply {
        t_0.apply();
    }
}

control proto(inout S s);
package top(proto p);
top(C()) main;

@fruffy Is there an easy way to test the output of a specific pass? This will get cleaned up by later passes so the change is not visible in the attached reference outputs.

kfcripps avatar Jul 18 '24 21:07 kfcripps

@fruffy Is there an easy way to test the output of a specific pass? This will get cleaned up by later passes so the change is not visible in the attached reference outputs.

Not exactly straightforward but take a look at https://github.com/p4lang/p4c/blob/main/test/gtest/strength_reduction.cpp

fruffy avatar Jul 18 '24 21:07 fruffy

@fruffy I was hoping for something that'd allow me to just pass --top4 RemoveDontcareArgs to the compiler and view the generated IR. Given that we'd need to add code to DontcareArgs to conditionally make this transformation (if I understand the referenced gtest correctly), I'd prefer to not add such gtests for this.

kfcripps avatar Jul 18 '24 23:07 kfcripps

I was hoping for something that'd allow me to just pass --top4 RemoveDontcareArgs to the compiler and view the generated IR

We could probably modify run-p4-sample.py and related files to support these kinds of tests.

kfcripps avatar Jul 18 '24 23:07 kfcripps

I was hoping for something that'd allow me to just pass --top4 RemoveDontcareArgs to the compiler and view the generated IR

We could probably modify run-p4-sample.py and related files to support these kinds of tests.

It might be fairly involved to extend run-p4-sample to support this broadly across a variety of passes. I'd guess you'd have to add a custom test with a custom reference file there.

With the gtest you could just expect the IR to have a specific structure after your pass. The input to the gtest is just a P4 program.

fruffy avatar Jul 19 '24 04:07 fruffy

@fruffy I was hoping for something that'd allow me to just pass --top4 RemoveDontcareArgs to the compiler and view the generated IR.

Well, you can just run the .test script with --top4 RemoveDontcareArgs and it will (should) dump the P4 program after that pass(es)

ChrisDodd avatar Jul 19 '24 04:07 ChrisDodd

We could probably modify run-p4-sample.py and related files to support these kinds of tests.

On second thought, this would be a bad idea as it would break as soon as someone would try adding a new RemoveDontcareArgs pass for some reason.

With the gtest you could just expect the IR to have a specific structure after your pass. The input to the gtest is just a P4 program.

It looks like https://github.com/p4lang/p4c/blob/main/test/gtest/strength_reduction.cpp is just running the entire set of frontend passes twice (once with some flag passed to the strength reduction pass) and checking the final output each time. It is not just running the strength reduction pass only and checking its exact output. Is my understanding not correct?

If my understanding is correct, are you suggesting to create and use my own version of FrontendTestCase::create(), which creates and runs a custom frontend that only runs the RemoveDontcareArgs pass (maybe also type inference first) instead of all of the frontend passes?

kfcripps avatar Jul 19 '24 09:07 kfcripps

@fruffy I think https://github.com/p4lang/p4c/blob/main/test/gtest/frontend_test.cpp was closer to what I needed. Added the gtest.

kfcripps avatar Jul 19 '24 11:07 kfcripps