17#ifndef FRONTENDS_P4_SIDEEFFECTS_H_ 
   18#define FRONTENDS_P4_SIDEEFFECTS_H_ 
   22#include "frontends/common/resolveReferences/referenceMap.h" 
   23#include "frontends/common/resolveReferences/resolveReferences.h" 
   24#include "frontends/p4/methodInstance.h" 
   25#include "frontends/p4/typeChecking/typeChecker.h" 
   35    const IR::P4Table *table;
 
   36    const IR::MethodCallExpression *call;
 
   39        setName(
"HasTableApply");
 
   42    void postorder(
const IR::MethodCallExpression *expression)
 override {
 
   44        if (!mi->isApply()) 
return;
 
   46        if (!am->object->is<IR::P4Table>()) 
return;
 
   47        BUG_CHECK(table == 
nullptr, 
"%1% and %2%: multiple table applications in one expression",
 
   49        table = am->object->to<IR::P4Table>();
 
   51        LOG3(
"Invoked table is " << dbp(table));
 
 
   74    void postorder(
const IR::MethodCallExpression *mce)
 override {
 
   75        if (refMap == 
nullptr || typeMap == 
nullptr) {
 
   88        if (bim->name.name != IR::Type_Header::isValid) {
 
   94    void postorder(
const IR::ConstructorCallExpression *cce)
 override {
 
  102        setName(
"SideEffects");
 
 
  106    static bool check(
const IR::Expression *expression, 
const Visitor *calledBy,
 
  110        se.setCalledBy(calledBy);
 
  111        expression->apply(se, ctxt);
 
 
  122            if (em->method->getAnnotation(IR::Annotation::noSideEffectsAnnotation)) {
 
  128            if (ef->method->getAnnotation(IR::Annotation::noSideEffectsAnnotation)) {
 
  134            if (ef->function->getAnnotation(IR::Annotation::noSideEffectsAnnotation)) {
 
  140            if (bim->name.name == IR::Type_Header::isValid) {
 
 
 
  184    std::set<const IR::Expression *> *added;
 
  190    std::set<const IR::Expression *> temporaries;
 
  192    cstring createTemporary(
const IR::Type *type);
 
  194                                        const IR::Expression *expression);
 
  195    bool mayAlias(
const IR::Expression *left, 
const IR::Expression *right,
 
  197    bool containsHeaderType(
const IR::Type *type);
 
  201        : typeMap(typeMap), added(added) {
 
  203        setName(
"DoSimplifyExpressions");
 
  206    const IR::Node *postorder(IR::Expression *expression) 
override;
 
  207    const IR::Node *preorder(IR::StructExpression *expression) 
override;
 
  208    const IR::Node *preorder(IR::ListExpression *expression) 
override;
 
  209    const IR::Node *preorder(IR::Literal *expression) 
override;
 
  210    const IR::Node *preorder(IR::ArrayIndex *expression) 
override;
 
  211    const IR::Node *preorder(IR::Member *expression) 
override;
 
  212    const IR::Node *preorder(IR::SelectExpression *expression) 
override;
 
  213    const IR::Node *preorder(IR::Operation_Unary *expression) 
override;
 
  214    const IR::Node *preorder(IR::Operation_Binary *expression) 
override;
 
  215    const IR::Node *shortCircuit(IR::Operation_Binary *expression);
 
  216    const IR::Node *preorder(IR::Mux *expression) 
override;
 
  217    const IR::Node *preorder(IR::LAnd *expression) 
override;
 
  218    const IR::Node *preorder(IR::LOr *expression) 
override;
 
  219    const IR::Node *preorder(IR::MethodCallExpression *mce) 
override;
 
  221    const IR::Node *preorder(IR::ConstructorCallExpression *cce)
 override {
 
  225    const IR::Node *preorder(IR::Property *prop)
 override {
 
  229    const IR::Node *preorder(IR::Annotation *anno)
 override {
 
  234    const IR::Node *postorder(IR::P4Parser *parser) 
override;
 
  235    const IR::Node *postorder(IR::Function *function) 
override;
 
  236    const IR::Node *postorder(IR::P4Control *control) 
override;
 
  237    const IR::Node *postorder(IR::P4Action *action) 
override;
 
  238    const IR::Node *postorder(IR::ParserState *state) 
override;
 
  239    const IR::Node *postorder(IR::AssignmentStatement *statement) 
override;
 
  240    const IR::Node *postorder(IR::MethodCallStatement *statement) 
override;
 
  241    const IR::Node *postorder(IR::ReturnStatement *statement) 
override;
 
  242    const IR::Node *preorder(IR::SwitchStatement *statement) 
override;
 
  243    const IR::Node *preorder(IR::IfStatement *statement) 
override;
 
  244    const IR::Node *preorder(IR::ForStatement *statement) 
override;
 
  245    const IR::Node *preorder(IR::ForInStatement *statement) 
override;
 
  248    void end_apply(
const IR::Node *) 
override;
 
 
  253    std::vector<const IR::Declaration_Variable *> declarations;
 
  254    std::vector<const IR::AssignmentStatement *> statements;
 
 
  299    std::map<const IR::P4Table *, TableInsertions *> toInsert;
 
  300    std::set<const IR::P4Table *> *invokedInKey;
 
  304        : typeMap(typeMap), invokedInKey(invokedInKey) {
 
  306        CHECK_NULL(invokedInKey);
 
  307        setName(
"KeySideEffect");
 
  312    virtual const IR::Node *doStatement(
const IR::Statement *statement,
 
  313                                        const IR::Expression *expression,
 
  316    const IR::Node *preorder(IR::Key *key) 
override;
 
  320    const IR::Node *postorder(IR::MethodCallStatement *statement)
 override {
 
  321        return doStatement(statement, statement->methodCall, getContext());
 
  323    const IR::Node *postorder(IR::IfStatement *statement)
 override {
 
  324        return doStatement(statement, statement->condition, getContext());
 
  326    const IR::Node *postorder(IR::SwitchStatement *statement)
 override {
 
  327        return doStatement(statement, statement->expression, getContext());
 
  329    const IR::Node *postorder(IR::AssignmentStatement *statement)
 override {
 
  330        return doStatement(statement, statement->right, getContext());
 
  332    const IR::Node *postorder(IR::KeyElement *element) 
override;
 
  333    const IR::Node *postorder(IR::P4Table *table) 
override;
 
  334    const IR::Node *preorder(IR::P4Table *table) 
override;
 
 
  344    std::set<const IR::P4Table *> *invokedInKey;
 
  348        : typeMap(typeMap), invokedInKey(invokedInKey) {
 
  349        CHECK_NULL(invokedInKey);
 
  350        setName(
"TableInKeys");
 
  353        invokedInKey->clear();
 
  354        return Inspector::init_apply(node);
 
  356    void postorder(
const IR::MethodCallExpression *mce)
 override {
 
  357        if (!findContext<IR::Key>()) 
return;
 
  359        hta.setCalledBy(
this);
 
  360        (void)mce->apply(hta, getContext());
 
  361        if (hta.table != 
nullptr) {
 
  362            LOG2(
"Table " << hta.table << 
" invoked in key of another table");
 
  363            invokedInKey->emplace(hta.table);
 
 
  378    void postorder(
const IR::MethodCallExpression *expression)
 override {
 
  379        if (findContext<IR::ActionList>()) {
 
  381            hta.setCalledBy(
this);
 
  382            (void)expression->apply(hta, getContext());
 
  383            if (hta.table != 
nullptr) {
 
  384                ::error(ErrorType::ERR_UNSUPPORTED, 
"%1%: table invocation in action argument",
 
 
  396    std::set<const IR::P4Table *> invokedInKey;
 
  398    std::set<const IR::Expression *> added;
 
  403        if (!typeChecking) typeChecking = 
new TypeChecking(
nullptr, typeMap);
 
  404        if (!skipSideEffectOrdering) {
 
  407            passes.push_back(typeChecking);
 
  409            passes.push_back(
new TablesInKeys(typeMap, &invokedInKey));
 
  412        setName(
"SideEffectOrdering");
 
 
Definition methodInstance.h:129
 
Definition methodInstance.h:254
 
Definition referenceMap.h:57
 
Convert expressions so that each expression contains at most one side effect.
Definition sideEffects.h:180
 
Definition methodInstance.h:181
 
Definition methodInstance.h:149
 
Definition methodInstance.h:226
 
Checks to see whether an IR node includes a table.apply() sub-expression.
Definition sideEffects.h:31
 
Definition sideEffects.h:295
 
static MethodInstance * resolve(const IR::MethodCallExpression *mce, const DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:27
 
Definition referenceMap.h:36
 
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:32
 
Definition sideEffects.h:391
 
Determines whether an expression may have method or constructor invocations.
Definition sideEffects.h:62
 
unsigned sideEffectCount
Number of side effects in this expression.
Definition sideEffects.h:72
 
SideEffects(DeclarationLookup *refMap, TypeMap *typeMap)
Definition sideEffects.h:101
 
const IR::Node * nodeWithSideEffect
Last visited side-effecting node. Null if no node has side effects.
Definition sideEffects.h:69
 
static bool hasSideEffect(const IR::MethodCallExpression *mce, DeclarationLookup *refMap, TypeMap *typeMap)
Definition sideEffects.h:115
 
static bool check(const IR::Expression *expression, const Visitor *calledBy, DeclarationLookup *refMap, TypeMap *typeMap, const Visitor::Context *ctxt=nullptr)
Definition sideEffects.h:106
 
Definition sideEffects.h:373
 
Definition sideEffects.h:342
 
Definition typeChecker.h:55
 
Definition pass_manager.h:143
 
Definition source_file.h:123
 
Definition applyOptionsPragmas.cpp:24
 
Definition sideEffects.h:251
 
T * to() noexcept
Definition rtti.h:226