[flang] Fortran IR: part 3, the FIR builder. This is a factory class for
authorEric Schweitz <eschweitz@nvidia.com>
Wed, 20 Feb 2019 20:18:04 +0000 (12:18 -0800)
committerEric Schweitz <eschweitz@nvidia.com>
Wed, 20 Feb 2019 20:18:04 +0000 (12:18 -0800)
helping to build a FIR representation.

Original-commit: flang-compiler/f18@9d937065ac52dc08ad34009c2f8beb6f4757b06f
Reviewed-on: https://github.com/flang-compiler/f18/pull/295
Tree-same-pre-rewrite: false

flang/lib/IntermediateRepresentation/builder.cc [new file with mode: 0644]
flang/lib/IntermediateRepresentation/builder.h [new file with mode: 0644]

diff --git a/flang/lib/IntermediateRepresentation/builder.cc b/flang/lib/IntermediateRepresentation/builder.cc
new file mode 100644 (file)
index 0000000..f79c99c
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
+//
+// 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 "builder.h"
+#include <iostream>
+
+namespace Fortran::IntermediateRepresentation {
+
+void IntermediateRepresentationBuilder::dump() const {
+  std::cerr << "builder state:\n";
+}
+
+}
diff --git a/flang/lib/IntermediateRepresentation/builder.h b/flang/lib/IntermediateRepresentation/builder.h
new file mode 100644 (file)
index 0000000..2c81925
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
+//
+// 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.
+
+#ifndef FORTRAN_INTERMEDIATEREPRESENTATION_BUILDER_H_
+#define FORTRAN_INTERMEDIATEREPRESENTATION_BUILDER_H_
+
+#include "stmt.h"
+#include <initializer_list>
+
+namespace Fortran::IntermediateRepresentation {
+
+struct IntermediateRepresentationBuilder {
+  explicit IntermediateRepresentationBuilder(BasicBlock &block)
+    : cursorRegion_{block.getParent()}, cursorBlock_{&block} {}
+  template<typename A> Statement &Insert(A &&s) {
+    CHECK(GetInsertionPoint());
+    auto *statement{new Statement(GetInsertionPoint(), s)};
+    return *statement;
+  }
+  template<typename A> Statement &InsertTerminator(A &&s) {
+    auto &statement{Insert(s)};
+    for (auto *block : s.succ_blocks()) {
+      block->addPred(GetInsertionPoint());
+    }
+    return statement;
+  }
+  void SetInsertionPoint(BasicBlock *bb) {
+    cursorBlock_ = bb;
+    cursorRegion_ = bb->getParent();
+  }
+  void ClearInsertionPoint() { cursorBlock_ = nullptr; }
+  BasicBlock *GetInsertionPoint() const { return cursorBlock_; }
+
+  Statement &CreateAlloc(const Expression *object) {
+    return Insert(AllocateStmt::Create(object));
+  }
+  Statement &CreateAssign(const PathVariable *lhs, const Expression *rhs) {
+    return Insert(AssignmentStmt::Create(lhs, rhs));
+  }
+  Statement &CreateAssign(const semantics::Symbol *lhs, BasicBlock *rhs) {
+    return Insert(LabelAssignStmt::Create(lhs, rhs));
+  }
+  Statement &CreateBranch(BasicBlock *block) {
+    return InsertTerminator(BranchStmt::Create(block));
+  }
+  Statement &CreateCall(const FunctionType *type, const Value *callee,
+      CallArguments &&arguments) {
+    return Insert(CallStmt::Create(type, callee, std::move(arguments)));
+  }
+  template<typename A>
+  Statement &CreateConditionalBranch(
+      A *condition, BasicBlock *trueBlock, BasicBlock *falseBlock) {
+    return InsertTerminator(
+        BranchStmt::Create(condition, trueBlock, falseBlock));
+  }
+  Statement &CreateDealloc(const Expression *object) {
+    return Insert(DeallocateStmt::Create(object));
+  }
+  template<typename A> Statement &CreateExpr(const A *a) {
+    return Insert(ExprStmt::Create(a));
+  }
+  Statement &CreateIOCall(
+      InputOutputCallType call, IOCallArguments &&arguments) {
+    return Insert(IORuntimeStmt::Create(call, std::move(arguments)));
+  }
+  Statement &CreateIndirectBr(
+      Variable *var, const std::vector<BasicBlock *> &potentials) {
+    return InsertTerminator(IndirectBrStmt::Create(var, potentials));
+  }
+  Statement &CreateNullify(const parser::NullifyStmt *statement) {
+    return Insert(DisassociateStmt::Create(statement));
+  }
+  Statement &CreatePointerAssign(const Expression *lhs, const Expression *rhs) {
+    return Insert(PointerAssignStmt::Create(lhs, rhs));
+  }
+  Statement &CreateRetVoid() { return InsertTerminator(ReturnStmt::Create()); }
+  template<typename A> Statement &CreateReturn(A *expr) {
+    return InsertTerminator(ReturnStmt::Create(expr));
+  }
+  Statement &CreateRuntimeCall(
+      RuntimeCallType call, RuntimeCallArguments &&arguments) {
+    return Insert(RuntimeStmt::Create(call, std::move(arguments)));
+  }
+  Statement &CreateSwitch(const Evaluation &condition, BasicBlock *defaultCase,
+      const SwitchStmt::ValueSuccPairListType &rest) {
+    return InsertTerminator(SwitchStmt::Create(condition, defaultCase, rest));
+  }
+  Statement &CreateSwitchCase(const Evaluation &condition,
+      BasicBlock *defaultCase,
+      const SwitchCaseStmt::ValueSuccPairListType &rest) {
+    return InsertTerminator(
+        SwitchCaseStmt::Create(condition, defaultCase, rest));
+  }
+  Statement &CreateSwitchType(const Evaluation &condition,
+      BasicBlock *defaultCase,
+      const SwitchTypeStmt::ValueSuccPairListType &rest) {
+    return InsertTerminator(
+        SwitchTypeStmt::Create(condition, defaultCase, rest));
+  }
+  Statement &CreateSwitchRank(const Evaluation &condition,
+      BasicBlock *defaultCase,
+      const SwitchRankStmt::ValueSuccPairListType &rest) {
+    return InsertTerminator(
+        SwitchRankStmt::Create(condition, defaultCase, rest));
+  }
+  Statement &CreateUnreachable() {
+    return InsertTerminator(UnreachableStmt::Create());
+  }
+
+  void PushBlock(BasicBlock *block) { blockStack_.push_back(block); }
+  BasicBlock *PopBlock() {
+    auto *block{blockStack_.back()};
+    blockStack_.pop_back();
+    return block;
+  }
+  void dump() const;
+  void SetCurrentRegion(Region *region) { cursorRegion_ = region; }
+  Region *GetCurrentRegion() const { return cursorRegion_; }
+
+private:
+  Region *cursorRegion_;
+  BasicBlock *cursorBlock_;
+  std::vector<BasicBlock *> blockStack_;
+};
+
+}
+
+#endif