Implement parser/IR support for CFG functions, basic blocks and return instruction.
This is pretty much minimal scaffolding for this step. Basic block arguments,
instructions, other terminators, a proper IR representation for
blocks/instructions, etc are all coming.
PiperOrigin-RevId: 201826439
diff --git a/lib/IR/AsmPrinter.cpp b/lib/IR/AsmPrinter.cpp
new file mode 100644
index 0000000..f857963
--- /dev/null
+++ b/lib/IR/AsmPrinter.cpp
@@ -0,0 +1,175 @@
+//===- AsmPrinter.cpp - MLIR Assembly Printer Implementation --------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// 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.
+// =============================================================================
+//
+// This file implements the MLIR AsmPrinter class, which is used to implement
+// the various print() methods on the core IR objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/CFGFunction.h"
+#include "mlir/IR/Module.h"
+#include "mlir/IR/Types.h"
+#include "mlir/Support/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/DenseMap.h"
+using namespace mlir;
+
+
+//===----------------------------------------------------------------------===//
+// Function printing
+//===----------------------------------------------------------------------===//
+
+static void printFunctionSignature(const Function *fn, raw_ostream &os) {
+ auto type = fn->getType();
+
+ os << "@" << fn->getName() << '(';
+ interleave(type->getInputs(),
+ [&](Type *eltType) { os << *eltType; },
+ [&]() { os << ", "; });
+ os << ')';
+
+ switch (type->getResults().size()) {
+ case 0: break;
+ case 1:
+ os << " -> " << *type->getResults()[0];
+ break;
+ default:
+ os << " -> (";
+ interleave(type->getResults(),
+ [&](Type *eltType) { os << *eltType; },
+ [&]() { os << ", "; });
+ os << ')';
+ break;
+ }
+}
+
+void ExtFunction::print(raw_ostream &os) const {
+ os << "extfunc ";
+ printFunctionSignature(this, os);
+ os << "\n";
+}
+
+//===----------------------------------------------------------------------===//
+// CFG Function printing
+//===----------------------------------------------------------------------===//
+
+namespace {
+class CFGFunctionState {
+public:
+ CFGFunctionState(const CFGFunction *function, raw_ostream &os);
+
+ const CFGFunction *getFunction() const { return function; }
+
+ void print();
+ void print(const BasicBlock *block);
+ void print(const TerminatorInst *inst);
+
+ unsigned getBBID(const BasicBlock *block) {
+ auto it = basicBlockIDs.find(block);
+ assert(it != basicBlockIDs.end() && "Block not in this function?");
+ return it->second;
+ }
+
+private:
+ const CFGFunction *function;
+ raw_ostream &os;
+ DenseMap<BasicBlock*, unsigned> basicBlockIDs;
+};
+} // end anonymous namespace
+
+CFGFunctionState::CFGFunctionState(const CFGFunction *function, raw_ostream &os)
+ : function(function), os(os) {
+
+ // Each basic block gets a unique ID per function.
+ unsigned blockID = 0;
+ for (auto *block : function->blockList)
+ basicBlockIDs[block] = blockID++;
+}
+
+void CFGFunctionState::print() {
+ os << "cfgfunc ";
+ printFunctionSignature(this->getFunction(), os);
+ os << " {\n";
+
+ for (auto *block : function->blockList)
+ print(block);
+ os << "}\n\n";
+}
+
+void CFGFunctionState::print(const BasicBlock *block) {
+ os << "bb" << getBBID(block) << ":\n";
+
+ // TODO Print arguments and instructions.
+
+ print(block->getTerminator());
+}
+
+void CFGFunctionState::print(const TerminatorInst *inst) {
+ switch (inst->getKind()) {
+ case TerminatorInst::Kind::Return:
+ os << " return\n";
+ break;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// print and dump methods
+//===----------------------------------------------------------------------===//
+
+void TerminatorInst::print(raw_ostream &os) const {
+ CFGFunctionState state(getFunction(), os);
+ state.print(this);
+}
+
+void TerminatorInst::dump() const {
+ print(llvm::errs());
+}
+
+void BasicBlock::print(raw_ostream &os) const {
+ CFGFunctionState state(getFunction(), os);
+ state.print();
+}
+
+void BasicBlock::dump() const {
+ print(llvm::errs());
+}
+
+void Function::print(raw_ostream &os) const {
+ switch (getKind()) {
+ case Kind::ExtFunc: return cast<ExtFunction>(this)->print(os);
+ case Kind::CFGFunc: return cast<CFGFunction>(this)->print(os);
+ }
+}
+
+void Function::dump() const {
+ print(llvm::errs());
+}
+
+void CFGFunction::print(raw_ostream &os) const {
+ CFGFunctionState state(this, os);
+ state.print();
+}
+
+void Module::print(raw_ostream &os) const {
+ for (auto *fn : functionList)
+ fn->print(os);
+}
+
+void Module::dump() const {
+ print(llvm::errs());
+}
+
diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp
new file mode 100644
index 0000000..ad8f71e
--- /dev/null
+++ b/lib/IR/BasicBlock.cpp
@@ -0,0 +1,22 @@
+//===- BasicBlock.cpp - MLIR BasicBlock Class -----------------------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// 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 "mlir/IR/BasicBlock.h"
+using namespace mlir;
+
+BasicBlock::BasicBlock(CFGFunction *function) : function(function) {
+}
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 54c9166..833c173 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -15,40 +15,26 @@
// limitations under the License.
// =============================================================================
-#include "mlir/IR/Function.h"
-#include "mlir/IR/Types.h"
-#include "mlir/Support/STLExtras.h"
-#include "llvm/Support/raw_ostream.h"
+#include "mlir/IR/CFGFunction.h"
+#include "llvm/ADT/StringRef.h"
using namespace mlir;
-Function::Function(StringRef name, FunctionType *type)
- : name(name.str()), type(type) {
+Function::Function(StringRef name, FunctionType *type, Kind kind)
+ : kind(kind), name(name.str()), type(type) {
}
-void Function::print(raw_ostream &os) {
- os << "extfunc @" << name << '(';
- interleave(type->getInputs(),
- [&](Type *eltType) { os << *eltType; },
- [&]() { os << ", "; });
- os << ')';
+//===----------------------------------------------------------------------===//
+// ExtFunction implementation.
+//===----------------------------------------------------------------------===//
- switch (type->getResults().size()) {
- case 0: break;
- case 1:
- os << " -> " << *type->getResults()[0];
- break;
- default:
- os << " -> (";
- interleave(type->getResults(),
- [&](Type *eltType) { os << *eltType; },
- [&]() { os << ", "; });
- os << ')';
- break;
- }
-
- os << "\n";
+ExtFunction::ExtFunction(StringRef name, FunctionType *type)
+ : Function(name, type, Kind::ExtFunc) {
}
-void Function::dump() {
- print(llvm::errs());
+//===----------------------------------------------------------------------===//
+// CFGFunction implementation.
+//===----------------------------------------------------------------------===//
+
+CFGFunction::CFGFunction(StringRef name, FunctionType *type)
+ : Function(name, type, Kind::CFGFunc) {
}
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
new file mode 100644
index 0000000..c123b86
--- /dev/null
+++ b/lib/IR/Instructions.cpp
@@ -0,0 +1,28 @@
+//===- Instructions.cpp - MLIR CFGFunction Instruction Classes ------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// 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 "mlir/IR/Instructions.h"
+#include "mlir/IR/BasicBlock.h"
+using namespace mlir;
+
+CFGFunction *TerminatorInst::getFunction() const {
+ return getBlock()->getFunction();
+}
+
+ReturnInst::ReturnInst(BasicBlock *block) : TerminatorInst(Kind::Return, block){
+}
+
diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp
index 37e8171..b41ad2b 100644
--- a/lib/IR/Module.cpp
+++ b/lib/IR/Module.cpp
@@ -16,19 +16,8 @@
// =============================================================================
#include "mlir/IR/Module.h"
-#include "llvm/Support/raw_ostream.h"
using namespace mlir;
Module::Module() {
}
-
-void Module::print(raw_ostream &os) {
- for (auto *fn : functionList)
- fn->print(os);
-}
-
-void Module::dump() {
- print(llvm::errs());
-}
-