Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parser graph generation support for graphs backend #969

Merged
merged 5 commits into from
Oct 30, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
main func and Graph methods are separed to different files:p4c-graphs…
….cpp,graphs.cpp
  • Loading branch information
c3m3gyanesh committed Oct 19, 2017
commit 3b75ee2b531bd5e6b474f42a2931da0dae20e419
1 change: 1 addition & 0 deletions backends/graphs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set (GRAPHS_SRCS
graphs.cpp
controls.cpp
parser.cpp
p4c-graphs.cpp
)

set (GRAPHS_HDRS
Expand Down
97 changes: 0 additions & 97 deletions backends/graphs/graphs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

#include "ir/ir.h"
#include "ir/json_loader.h"
#include "lib/log.h"
#include "lib/error.h"
#include "lib/exceptions.h"
#include "lib/gc.h"
#include "lib/crash.h"
#include "lib/nullstream.h"
#include "frontends/common/parseInput.h"
#include "frontends/p4/evaluator/evaluator.h"
#include "frontends/p4/frontend.h"

#include "graphs.h"

namespace graphs {

class MidEnd : public PassManager {
public:
P4::ReferenceMap refMap;
P4::TypeMap typeMap;
IR::ToplevelBlock *toplevel = nullptr;

explicit MidEnd(CompilerOptions& options);
IR::ToplevelBlock* process(const IR::P4Program *&program) {
program = program->apply(*this);
return toplevel;
}
};

MidEnd::MidEnd(CompilerOptions& options) {
bool isv1 = options.langVersion == CompilerOptions::FrontendVersion::P4_14;
refMap.setIsV1(isv1);
auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap);
setName("MidEnd");

addPasses({
evaluator,
new VisitFunctor([this, evaluator]() { toplevel = evaluator->getToplevelBlock(); }),
});
}

class Graphs::GraphAttributeSetter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally think that the main function for the backend and the Graph methods implementation belong in 2 different files; apart from that it looks ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a new file "p4c-graphs.cpp" to accommodate main funcion.

public:
void operator()(Graph &g) const {
Expand Down Expand Up @@ -165,72 +135,5 @@ Graphs::vertex_t Graphs::add_and_connect_vertex(const cstring &name, VertexType
return v;
}

class Options : public CompilerOptions {
public:
cstring graphsDir{"."};
Options() {
registerOption("--graphs-dir", "dir",
[this](const char* arg) { graphsDir = arg; return true; },
"Use this directory to dump graphs in dot format "
"(default is current working directory)\n");
}
};


} // namespace graphs

int main(int argc, char *const argv[]) {
setup_gc_logging();
setup_signals();

graphs::Options options;
options.langVersion = CompilerOptions::FrontendVersion::P4_16;
options.compilerVersion = "0.0.5";

if (options.process(argc, argv) != nullptr)
options.setInputFile();
if (::errorCount() > 0)
return 1;

auto hook = options.getDebugHook();

auto program = P4::parseP4File(options);
if (program == nullptr || ::errorCount() > 0)
return 1;

try {
P4::FrontEnd fe;
fe.addDebugHook(hook);
program = fe.run(options, program);
} catch (const Util::P4CExceptionBase &bug) {
std::cerr << bug.what() << std::endl;
return 1;
}
if (program == nullptr || ::errorCount() > 0)
return 1;

graphs::MidEnd midEnd(options);
midEnd.addDebugHook(hook);
const IR::ToplevelBlock *top = nullptr;
try {
top = midEnd.process(program);
if (options.dumpJsonFile)
JSONGenerator(*openFile(options.dumpJsonFile, true)) << program << std::endl;
} catch (const Util::P4CExceptionBase &bug) {
std::cerr << bug.what() << std::endl;
return 1;
}
if (::errorCount() > 0)
return 1;

LOG1("Generating graphs under " << options.graphsDir);
LOG1("Generating control graphs");
graphs::ControlGraphs cgen(&midEnd.refMap, &midEnd.typeMap, options.graphsDir);
top->getMain()->apply(cgen);

LOG1("Generating parser graphs");
graphs::ParserGraphs pgen(&midEnd.refMap, &midEnd.typeMap, options.graphsDir);
top->getMain()->apply(pgen);

return ::errorCount() > 0;
}
124 changes: 124 additions & 0 deletions backends/graphs/p4c-graphs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
Copyright 2013-present Barefoot Networks, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "ir/ir.h"
#include "lib/log.h"
#include "lib/error.h"
#include "lib/exceptions.h"
#include "lib/gc.h"
#include "lib/crash.h"
#include "lib/nullstream.h"
#include "frontends/common/parseInput.h"
#include "frontends/p4/evaluator/evaluator.h"
#include "frontends/p4/frontend.h"

#include "graphs.h"

namespace graphs {

class MidEnd : public PassManager {
public:
P4::ReferenceMap refMap;
P4::TypeMap typeMap;
IR::ToplevelBlock *toplevel = nullptr;

explicit MidEnd(CompilerOptions& options);
IR::ToplevelBlock* process(const IR::P4Program *&program) {
program = program->apply(*this);
return toplevel;
}
};

MidEnd::MidEnd(CompilerOptions& options) {
bool isv1 = options.langVersion == CompilerOptions::FrontendVersion::P4_14;
refMap.setIsV1(isv1);
auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap);
setName("MidEnd");

addPasses({
evaluator,
new VisitFunctor([this, evaluator]() { toplevel = evaluator->getToplevelBlock(); }),
});
}

class Options : public CompilerOptions {
public:
cstring graphsDir{"."};
Options() {
registerOption("--graphs-dir", "dir",
[this](const char* arg) { graphsDir = arg; return true; },
"Use this directory to dump graphs in dot format "
"(default is current working directory)\n");
}
};

} // namespace graphs

int main(int argc, char *const argv[]) {
setup_gc_logging();
setup_signals();

graphs::Options options;
options.langVersion = CompilerOptions::FrontendVersion::P4_16;
options.compilerVersion = "0.0.5";

if (options.process(argc, argv) != nullptr)
options.setInputFile();
if (::errorCount() > 0)
return 1;

auto hook = options.getDebugHook();

auto program = P4::parseP4File(options);
if (program == nullptr || ::errorCount() > 0)
return 1;

try {
P4::FrontEnd fe;
fe.addDebugHook(hook);
program = fe.run(options, program);
} catch (const Util::P4CExceptionBase &bug) {
std::cerr << bug.what() << std::endl;
return 1;
}
if (program == nullptr || ::errorCount() > 0)
return 1;

graphs::MidEnd midEnd(options);
midEnd.addDebugHook(hook);
const IR::ToplevelBlock *top = nullptr;
try {
top = midEnd.process(program);
if (options.dumpJsonFile)
JSONGenerator(*openFile(options.dumpJsonFile, true)) << program << std::endl;
} catch (const Util::P4CExceptionBase &bug) {
std::cerr << bug.what() << std::endl;
return 1;
}
if (::errorCount() > 0)
return 1;

LOG1("Generating graphs under " << options.graphsDir);
LOG1("Generating control graphs");
graphs::ControlGraphs cgen(&midEnd.refMap, &midEnd.typeMap, options.graphsDir);
top->getMain()->apply(cgen);

LOG1("Generating parser graphs");
graphs::ParserGraphs pgen(&midEnd.refMap, &midEnd.typeMap, options.graphsDir);
top->getMain()->apply(pgen);

return ::errorCount() > 0;
}