diff options
author | Ruiling Song <ruiling.song@intel.com> | 2014-11-26 09:38:51 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-12-01 15:12:15 +0800 |
commit | 265564857adcc6d60b3efde4f886654c99f9c510 (patch) | |
tree | 6c045cd72f8e68b4375ccf932b784c237bd27246 | |
parent | ef83b3f5d33bcfe0a328b679863f0cbb3afa1700 (diff) |
GBE: Output CFG of Gen IR to dot file.
Add an environment variable 'OCL_OUTPUT_CFG_GEN_IR' to control it.
Signed-off-by: Ruiling Song <ruiling.song@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r-- | backend/src/ir/function.cpp | 21 | ||||
-rw-r--r-- | backend/src/ir/function.hpp | 2 | ||||
-rw-r--r-- | backend/src/llvm/llvm_to_gen.cpp | 3 |
3 files changed, 26 insertions, 0 deletions
diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp index 79837784..6dde6e2b 100644 --- a/backend/src/ir/function.cpp +++ b/backend/src/ir/function.cpp @@ -281,6 +281,27 @@ namespace ir { }); } + void Function::outputCFG(void) { + std::string fileName = getName() + std::string(".dot"); + ::FILE *fp = fopen(fileName.c_str(), "w"); + if (fp == NULL) return; + + printf("writing Gen IR CFG to %s\n", fileName.c_str()); + fprintf(fp, "digraph \"%s\" {\n", getName().c_str()); + this->foreachBlock([this, fp](BasicBlock &bb) { + uint32_t lid = bb.getLabelIndex(); + fprintf(fp, "Node%d [shape=record, label=\"{%d}\"];\n", lid, lid); + set<BasicBlock*> &succ = bb.successors; + for (auto x : succ) { + uint32_t next = x->getLabelIndex(); + fprintf(fp, "Node%d -> Node%d\n", lid, next); + } + }); + fprintf(fp, "}\n"); + fclose(fp); + } + + std::ostream &operator<< (std::ostream &out, const Function &fn) { out << ".decl_function " << fn.getName() << std::endl; diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp index 0381095b..1163a195 100644 --- a/backend/src/ir/function.hpp +++ b/backend/src/ir/function.hpp @@ -428,6 +428,8 @@ namespace ir { /*! Get surface starting address register from bti */ Register getSurfaceBaseReg(uint8_t bti) const; void appendSurface(uint8_t bti, Register reg); + /*! Output the control flow graph to .dot file */ + void outputCFG(); private: friend class Context; //!< Can freely modify a function std::string name; //!< Function name diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp index eb75ba11..e1bf12f0 100644 --- a/backend/src/llvm/llvm_to_gen.cpp +++ b/backend/src/llvm/llvm_to_gen.cpp @@ -74,6 +74,7 @@ namespace gbe { BVAR(OCL_OUTPUT_CFG, false); BVAR(OCL_OUTPUT_CFG_ONLY, false); + BVAR(OCL_OUTPUT_CFG_GEN_IR, false); using namespace llvm; void runFuntionPass(Module &mod, TargetLibraryInfo *libraryInfo, const DataLayout &DL) @@ -297,6 +298,8 @@ namespace gbe analysis::ControlTree *ct = new analysis::ControlTree(iter->second); ct->analyze(); delete ct; + if (OCL_OUTPUT_CFG_GEN_IR) + iter->second->outputCFG(); iter++; } |