[flang] react to more review comments
authorEric Schweitz <eschweitz@nvidia.com>
Thu, 28 Feb 2019 20:26:43 +0000 (12:26 -0800)
committerEric Schweitz <eschweitz@nvidia.com>
Mon, 11 Mar 2019 15:56:36 +0000 (08:56 -0700)
Original-commit: flang-compiler/f18@b685d8a588287ac7683fd5626023c0de70fcc69b
Reviewed-on: https://github.com/flang-compiler/f18/pull/319
Tree-same-pre-rewrite: false

flang/lib/FIR/afforestation.cc
flang/lib/FIR/basicblock.cc
flang/lib/FIR/builder.h
flang/lib/FIR/common.h
flang/lib/FIR/region.h
flang/lib/FIR/statement.def
flang/lib/FIR/statements.cc
flang/lib/FIR/statements.h

index 5d114fc..56400e9 100644 (file)
@@ -504,15 +504,14 @@ template<typename STMTTYPE, typename CT>
 Evaluation GetSwitchSelector(const CT *selectConstruct) {
   const auto &selector{std::get<parser::Selector>(
       std::get<parser::Statement<STMTTYPE>>(selectConstruct->t).statement.t)};
-  return std::visit(
-      common::visitors{
-          [](const parser::Expr &expression) {
-            return Evaluation{expression.typedExpr.get()};
-          },
-          [](const parser::Variable &variable) {
-            return Evaluation{&variable};
-          },
-      },
+  return std::visit(common::visitors{
+                        [](const parser::Expr &expression) {
+                          return Evaluation{expression.typedExpr.get()};
+                        },
+                        [](const parser::Variable &variable) {
+                          return Evaluation{&variable};
+                        },
+                    },
       selector.u);
 }
 Evaluation GetSwitchRankSelector(
@@ -852,8 +851,7 @@ struct SwitchTypeArguments {
   std::vector<LinearLabelRef> labels;
 };
 
-template<typename T>
-bool IsDefault(const typename T::ValueType &valueType) {
+template<typename T> bool IsDefault(const typename T::ValueType &valueType) {
   return std::holds_alternative<typename T::Default>(valueType);
 }
 
@@ -925,19 +923,18 @@ static std::vector<SwitchRankStmt::ValueType> populateSwitchValues(
     auto &rank{std::get<parser::SelectRankCaseStmt::Rank>(
         std::get<parser::Statement<parser::SelectRankCaseStmt>>(v.t)
             .statement.t)};
-    std::visit(
-        common::visitors{
-            [&](const parser::ScalarIntConstantExpr &expression) {
-              result.emplace_back(SwitchRankStmt::Exactly{
-                  expression.thing.thing.thing->typedExpr.get()});
-            },
-            [&](const parser::Star &) {
-              result.emplace_back(SwitchRankStmt::AssumedSize{});
-            },
-            [&](const parser::Default &) {
-              result.emplace_back(SwitchRankStmt::Default{});
-            },
-        },
+    std::visit(common::visitors{
+                   [&](const parser::ScalarIntConstantExpr &expression) {
+                     result.emplace_back(SwitchRankStmt::Exactly{
+                         expression.thing.thing.thing->typedExpr.get()});
+                   },
+                   [&](const parser::Star &) {
+                     result.emplace_back(SwitchRankStmt::AssumedSize{});
+                   },
+                   [&](const parser::Default &) {
+                     result.emplace_back(SwitchRankStmt::Default{});
+                   },
+               },
         rank.u);
   }
   return result;
@@ -949,20 +946,19 @@ static std::vector<SwitchTypeStmt::ValueType> populateSwitchValues(
   for (auto &v : list) {
     auto &guard{std::get<parser::TypeGuardStmt::Guard>(
         std::get<parser::Statement<parser::TypeGuardStmt>>(v.t).statement.t)};
-    std::visit(
-        common::visitors{
-            [&](const parser::TypeSpec &typeSpec) {
-              result.emplace_back(
-                  SwitchTypeStmt::TypeSpec{typeSpec.declTypeSpec});
-            },
-            [&](const parser::DerivedTypeSpec &derivedTypeSpec) {
-              result.emplace_back(
-                  SwitchTypeStmt::DerivedTypeSpec{nullptr /*FIXME*/});
-            },
-            [&](const parser::Default &) {
-              result.emplace_back(SwitchTypeStmt::Default{});
-            },
-        },
+    std::visit(common::visitors{
+                   [&](const parser::TypeSpec &typeSpec) {
+                     result.emplace_back(
+                         SwitchTypeStmt::TypeSpec{typeSpec.declTypeSpec});
+                   },
+                   [&](const parser::DerivedTypeSpec &derivedTypeSpec) {
+                     result.emplace_back(
+                         SwitchTypeStmt::DerivedTypeSpec{nullptr /*FIXME*/});
+                   },
+                   [&](const parser::Default &) {
+                     result.emplace_back(SwitchTypeStmt::Default{});
+                   },
+               },
         guard.u);
   }
   return result;
@@ -1017,22 +1013,21 @@ static void buildMultiwayDefaultNext(SwitchArguments &result) {
 }
 static SwitchArguments ComposeSwitchArgs(const LinearSwitch &op) {
   SwitchArguments result{nullptr, unspecifiedLabel, {}, op.refs};
-  std::visit(
-      common::visitors{
-          [](const auto *) { WRONG_PATH(); },
-          [&](const parser::ComputedGotoStmt *c) {
-            result.exp = std::get<parser::ScalarIntExpr>(c->t)
-                             .thing.thing->typedExpr.get();
-            buildMultiwayDefaultNext(result);
-          },
-          [&](const parser::ArithmeticIfStmt *c) {
-            result.exp = std::get<parser::Expr>(c->t).typedExpr.get();
-          },
-          [&](const parser::CallStmt *c) {
-            result.exp = nullptr;  // fixme - result of call
-            buildMultiwayDefaultNext(result);
-          },
-      },
+  std::visit(common::visitors{
+                 [](const auto *) { WRONG_PATH(); },
+                 [&](const parser::ComputedGotoStmt *c) {
+                   result.exp = std::get<parser::ScalarIntExpr>(c->t)
+                                    .thing.thing->typedExpr.get();
+                   buildMultiwayDefaultNext(result);
+                 },
+                 [&](const parser::ArithmeticIfStmt *c) {
+                   result.exp = std::get<parser::Expr>(c->t).typedExpr.get();
+                 },
+                 [&](const parser::CallStmt *c) {
+                   result.exp = nullptr;  // fixme - result of call
+                   buildMultiwayDefaultNext(result);
+                 },
+             },
       op.u);
   return result;
 }
@@ -1207,20 +1202,20 @@ struct FortranIRLowering {
   const Expression *CreatePointerValue(
       const parser::PointerAssignmentStmt *stmt) {
     // TODO: build a RHS expression to assign to a POINTER
-    return static_cast<const Expression *>(nullptr);
+    return nullptr;
   }
-  const Expression *CreateAllocationValue(const parser::Allocation *allocation,
+  Type CreateAllocationValue(const parser::Allocation *allocation,
       const parser::AllocateStmt *statement) {
     auto &obj{std::get<parser::AllocateObject>(allocation->t)};
     (void)obj;
     // TODO: build an expression for the allocation
-    return static_cast<const Expression *>(nullptr);
+    return nullptr;
   }
-  const Expression *CreateDeallocationValue(
+  const AllocateInsn *CreateDeallocationValue(
       const parser::AllocateObject *allocateObject,
       const parser::DeallocateStmt *statement) {
     // TODO: build an expression for the allocation
-    return static_cast<const Expression *>(nullptr);
+    return nullptr;
   }
 
   // IO argument translations ...
@@ -1332,7 +1327,7 @@ struct FortranIRLowering {
   // CALL translations ...
   const Value *CreateCalleeValue(
       const parser::ProcedureDesignator &designator) {
-    return static_cast<const Value *>(nullptr);
+    return nullptr;
   }
   CallArguments CreateCallArguments(
       const std::list<parser::ActualArgSpec> &arguments) {
@@ -1360,7 +1355,7 @@ struct FortranIRLowering {
                   CreateBackspaceArguments(statement->v));
             },
             [&](const common::Indirection<parser::CallStmt> &statement) {
-              builder_->CreateCall(static_cast<const FunctionType *>(nullptr),
+              builder_->CreateCall(nullptr,
                   CreateCalleeValue(
                       std::get<parser::ProcedureDesignator>(statement->v.t)),
                   CreateCallArguments(
@@ -1582,27 +1577,27 @@ struct FortranIRLowering {
               },
               [&](const LinearReturn &linearReturn) {
                 CheckInsertionPoint();
-                std::visit(
-                    common::visitors{
-                        [&](const parser::FailImageStmt *s) {
-                          builder_->CreateRuntimeCall(RuntimeCallFailImage,
-                              CreateFailImageArguments(*s));
-                          builder_->CreateUnreachable();
-                        },
-                        [&](const parser::ReturnStmt *s) {
-                          if (s->v) {
-                            builder_->CreateReturn(
-                                s->v->thing.thing->typedExpr.get());
-                          } else {
-                            builder_->CreateRetVoid();
-                          }
-                        },
-                        [&](const parser::StopStmt *s) {
-                          builder_->CreateRuntimeCall(
-                              RuntimeCallStop, CreateStopArguments(*s));
-                          builder_->CreateUnreachable();
-                        },
-                    },
+                std::visit(common::visitors{
+                               [&](const parser::FailImageStmt *s) {
+                                 builder_->CreateRuntimeCall(
+                                     RuntimeCallFailImage,
+                                     CreateFailImageArguments(*s));
+                                 builder_->CreateUnreachable();
+                               },
+                               [&](const parser::ReturnStmt *s) {
+                                 if (s->v) {
+                                   builder_->CreateReturn(
+                                       s->v->thing.thing->typedExpr.get());
+                                 } else {
+                                   builder_->CreateRetVoid();
+                                 }
+                               },
+                               [&](const parser::StopStmt *s) {
+                                 builder_->CreateRuntimeCall(
+                                     RuntimeCallStop, CreateStopArguments(*s));
+                                 builder_->CreateUnreachable();
+                               },
+                           },
                     linearReturn.u);
                 builder_->ClearInsertionPoint();
               },
@@ -1664,37 +1659,37 @@ struct FortranIRLowering {
               },
               [&](const LinearSwitch &linearSwitch) {
                 CheckInsertionPoint();
-                std::visit(
-                    common::visitors{
-                        [&](auto) {
-                          auto args{ComposeSwitchArgs(linearSwitch)};
-                          AddOrQueueSwitch<SwitchStmt>(args.exp, args.defLab,
-                              args.values, args.labels, CreateSwitchHelper);
-                        },
-                        [&](const parser::CaseConstruct *caseConstruct) {
-                          auto args{ComposeSwitchCaseArguments(
-                              caseConstruct, linearSwitch.refs)};
-                          AddOrQueueSwitch<SwitchCaseStmt>(args.exp,
-                              args.defLab, args.ranges, args.labels,
-                              CreateSwitchCaseHelper);
-                        },
-                        [&](const parser::SelectRankConstruct
-                                *selectRankConstruct) {
-                          auto args{ComposeSwitchRankArguments(
-                              selectRankConstruct, linearSwitch.refs)};
-                          AddOrQueueSwitch<SwitchRankStmt>(args.exp,
-                              args.defLab, args.ranks, args.labels,
-                              CreateSwitchRankHelper);
-                        },
-                        [&](const parser::SelectTypeConstruct
-                                *selectTypeConstruct) {
-                          auto args{ComposeSwitchTypeArguments(
-                              selectTypeConstruct, linearSwitch.refs)};
-                          AddOrQueueSwitch<SwitchTypeStmt>(args.exp,
-                              args.defLab, args.types, args.labels,
-                              CreateSwitchTypeHelper);
-                        },
-                    },
+                std::visit(common::visitors{
+                               [&](auto) {
+                                 auto args{ComposeSwitchArgs(linearSwitch)};
+                                 AddOrQueueSwitch<SwitchStmt>(args.exp,
+                                     args.defLab, args.values, args.labels,
+                                     CreateSwitchHelper);
+                               },
+                               [&](const parser::CaseConstruct *caseConstruct) {
+                                 auto args{ComposeSwitchCaseArguments(
+                                     caseConstruct, linearSwitch.refs)};
+                                 AddOrQueueSwitch<SwitchCaseStmt>(args.exp,
+                                     args.defLab, args.ranges, args.labels,
+                                     CreateSwitchCaseHelper);
+                               },
+                               [&](const parser::SelectRankConstruct
+                                       *selectRankConstruct) {
+                                 auto args{ComposeSwitchRankArguments(
+                                     selectRankConstruct, linearSwitch.refs)};
+                                 AddOrQueueSwitch<SwitchRankStmt>(args.exp,
+                                     args.defLab, args.ranks, args.labels,
+                                     CreateSwitchRankHelper);
+                               },
+                               [&](const parser::SelectTypeConstruct
+                                       *selectTypeConstruct) {
+                                 auto args{ComposeSwitchTypeArguments(
+                                     selectTypeConstruct, linearSwitch.refs)};
+                                 AddOrQueueSwitch<SwitchTypeStmt>(args.exp,
+                                     args.defLab, args.types, args.labels,
+                                     CreateSwitchTypeHelper);
+                               },
+                           },
                     linearSwitch.u);
                 builder_->ClearInsertionPoint();
               },
@@ -1779,15 +1774,14 @@ struct FortranIRLowering {
                     linearConstruct.u);
                 auto next{iter};
                 const auto &nextOp{*(++next)};
-                std::visit(
-                    common::visitors{
-                        [](const auto &) {},
-                        [&](const LinearLabel &linearLabel) {
-                          blockMap_.insert({linearLabel.get(),
-                              builder_->GetInsertionPoint()});
-                          ++iter;
-                        },
-                    },
+                std::visit(common::visitors{
+                               [](const auto &) {},
+                               [&](const LinearLabel &linearLabel) {
+                                 blockMap_.insert({linearLabel.get(),
+                                     builder_->GetInsertionPoint()});
+                                 ++iter;
+                               },
+                           },
                     nextOp.u);
               },
               [&](const LinearEndConstruct &linearConstruct) {
@@ -1922,7 +1916,7 @@ struct FortranIRLowering {
       const std::vector<LinearLabelRef> &labels) {
     auto useLabels{labels.empty() ? GetAssign(ad, symbol) : labels};
     auto defer{false};
-    IndirectBrStmt::TargetListType blocks;
+    IndirectBranchStmt::TargetListType blocks;
     for (auto lab : useLabels) {
       auto iter{blockMap_.find(lab)};
       if (iter == blockMap_.end()) {
index 3c8989a..e43c7db 100644 (file)
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 #include "program.h"
-#include "stmt.h"
+#include "statements.h"
 
 namespace Fortran::FIR {
 
@@ -34,7 +34,9 @@ void BasicBlock::insertBefore(Statement *stmt, Statement *before) {
 
 void BasicBlock::addPred(BasicBlock *bb) {
   for (auto *p : preds_) {
-    if (p == bb) return;
+    if (p == bb) {
+      return;
+    }
   }
   preds_.push_back(bb);
 }
index c962dac..d4c6d92 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef FORTRAN_FIR_BUILDER_H_
 #define FORTRAN_FIR_BUILDER_H_
 
-#include "stmt.h"
+#include "statements.h"
 #include <initializer_list>
 
 namespace Fortran::FIR {
@@ -42,8 +42,8 @@ struct FIRBuilder {
   void ClearInsertionPoint() { cursorBlock_ = nullptr; }
   BasicBlock *GetInsertionPoint() const { return cursorBlock_; }
 
-  Statement &CreateAlloc(const Expression *object) {
-    return Insert(AllocateStmt::Create(object));
+  Statement &CreateAlloc(Type type) {
+    return Insert(AllocateInsn::Create(type));
   }
   Statement &CreateAssign(const PathVariable *lhs, const Expression *rhs) {
     return Insert(AssignmentStmt::Create(lhs, rhs));
@@ -64,22 +64,20 @@ struct FIRBuilder {
     return InsertTerminator(
         BranchStmt::Create(condition, trueBlock, falseBlock));
   }
-  Statement &CreateDealloc(const Expression *object) {
-    return Insert(DeallocateStmt::Create(object));
+  Statement &CreateDealloc(const AllocateInsn *alloc) {
+    return Insert(DeallocateInsn::Create(alloc));
   }
   template<typename A> Statement &CreateExpr(const A *a) {
     return Insert(ApplyExprStmt::Create(a));
   }
-  Statement &CreateIOCall(
-      InputOutputCallType call, IOCallArguments &&arguments) {
-    return Insert(IORuntimeStmt::Create(call, std::move(arguments)));
+  Statement &CreateIOCall(InputOutputCallType c, IOCallArguments &&a) {
+    return Insert(IORuntimeStmt::Create(c, std::move(a)));
   }
-  Statement &CreateIndirectBr(
-      Variable *var, const std::vector<BasicBlock *> &potentials) {
-    return InsertTerminator(IndirectBrStmt::Create(var, potentials));
+  Statement &CreateIndirectBr(Variable *v, const std::vector<BasicBlock *> &p) {
+    return InsertTerminator(IndirectBranchStmt::Create(v, p));
   }
-  Statement &CreateNullify(const parser::NullifyStmt *statement) {
-    return Insert(DisassociateStmt::Create(statement));
+  Statement &CreateNullify(const parser::NullifyStmt *s) {
+    return Insert(DisassociateInsn::Create(s));
   }
   Statement &CreatePointerAssign(const Expression *lhs, const Expression *rhs) {
     return Insert(PointerAssignStmt::Create(lhs, rhs));
@@ -108,11 +106,9 @@ struct FIRBuilder {
     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 &CreateSwitchRank(const Evaluation &c, BasicBlock *d,
+      const SwitchRankStmt::ValueSuccPairListType &r) {
+    return InsertTerminator(SwitchRankStmt::Create(c, d, r));
   }
   Statement &CreateUnreachable() {
     return InsertTerminator(UnreachableStmt::Create());
index e426ed0..b5660a9 100644 (file)
@@ -50,24 +50,13 @@ using FunctionType = evaluate::SomeType;  // TODO: what should this be?
 using AttributeList = std::vector<Attribute>;
 enum struct LinkageTypes { Public, Hidden, External };
 using Expression = evaluate::GenericExprWrapper;
-#if 0
-struct Variable {
-  // TODO: should semantics::Symbol be removed?
-  template<typename... Ts> struct GVT {
-    using type =
-        std::variant<const semantics::Symbol *, evaluate::Variable<Ts>...>;
-  };
-  Variable(const semantics::Symbol *symbol) : u{symbol} {}
-  common::OverMembers<GVT, evaluate::AllIntrinsicTypes>::type u;
-};
-#endif
-
 using Variable = const semantics::Symbol *;
 using PathVariable = const parser::Variable;
 using Scope = const semantics::Scope;
 using Value = Expression;
 using PHIPair = std::pair<Value *, BasicBlock *>;
 using CallArguments = std::vector<const Expression *>;
+using Type = const semantics::DeclTypeSpec *;  // FIXME
 
 enum InputOutputCallType {
   InputOutputCallBackspace = 11,
index 73e77d0..756d77d 100644 (file)
@@ -16,7 +16,7 @@
 #define FORTRAN_FIR_REGION_H_
 
 #include "procedure.h"
-#include "stmt.h"
+#include "statements.h"
 #include "../semantics/semantics.h"
 
 namespace Fortran::FIR {
index 713fc85..df43afc 100644 (file)
 // block of the program.   Every basic block must end with one of these
 // instructions for it to be a well formed basic block.
 FIRST_TERM_STMT(1)
-HANDLE_TERM_STMT(1, Ret,         ReturnStmt)
-HANDLE_TERM_STMT(2, Br,          BranchStmt)
-HANDLE_TERM_STMT(3, Switch,      SwitchStmt)
-HANDLE_TERM_STMT(4, SwitchCase,  SwitchCaseStmt)
-HANDLE_TERM_STMT(5, SwitchType,  SwitchTypeStmt)
-HANDLE_TERM_STMT(6, SwitchRank,  SwitchRankStmt)
-HANDLE_TERM_STMT(7, IndirectBr,  IndirectBrStmt)
-HANDLE_TERM_STMT(8, Unreachable, UnreachableStmt)
+HANDLE_TERM_STMT( 1, Return,         ReturnStmt)
+HANDLE_TERM_STMT( 2, Branch,         BranchStmt)
+HANDLE_TERM_STMT( 3, Switch,         SwitchStmt)
+HANDLE_TERM_STMT( 4, SwitchCase,     SwitchCaseStmt)
+HANDLE_TERM_STMT( 5, SwitchType,     SwitchTypeStmt)
+HANDLE_TERM_STMT( 6, SwitchRank,     SwitchRankStmt)
+HANDLE_TERM_STMT( 7, IndirectBranch, IndirectBranchStmt)
+HANDLE_TERM_STMT( 8, Unreachable,    UnreachableStmt)
 LAST_TERM_STMT(8)
 
 // Standard actions - These instructions capture computations as
 // evaluate::expressions
 FIRST_COMPUTE_STMT(9)
-HANDLE_COMPUTE_STMT(9,  Assign,    AssignmentStmt)
-HANDLE_COMPUTE_STMT(10, PtrAssign, PointerAssignStmt)
-HANDLE_COMPUTE_STMT(11, LblAssign, LabelAssignStmt)
-HANDLE_COMPUTE_STMT(12, ApplyExpr, ApplyExprStmt)
-LAST_COMPUTE_STMT(12)
+HANDLE_COMPUTE_STMT( 9, Assign,        AssignmentStmt)
+HANDLE_COMPUTE_STMT(10, PointerAssign, PointerAssignStmt)
+HANDLE_COMPUTE_STMT(11, LabelAssign,   LabelAssignStmt)
+HANDLE_COMPUTE_STMT(12, ApplyExpr,     ApplyExprStmt)
+HANDLE_COMPUTE_STMT(13, LocateExpr,    LocateExprStmt)
+LAST_COMPUTE_STMT(13)
 
 // Memory operators - These instructions capture ALLOCATE and DEALLOCATE
 // Fortran statements
-FIRST_MEMORY_STMT(13)
-HANDLE_MEMORY_STMT(13, Alloc,        AllocateStmt)
-HANDLE_MEMORY_STMT(14, Dealloc,      DeallocateStmt)
-HANDLE_MEMORY_STMT(15, AllocLocal,   AllocLocalInsn)
-HANDLE_MEMORY_STMT(16, Load,         LoadInsn)
-HANDLE_MEMORY_STMT(17, Store,        StoreInsn)
-HANDLE_MEMORY_STMT(18, Disassociate, DisassociateStmt)
-LAST_MEMORY_STMT(18)
+FIRST_MEMORY_STMT(14)
+HANDLE_MEMORY_STMT(14, Allocate,     AllocateInsn)
+HANDLE_MEMORY_STMT(15, Deallocate,   DeallocateInsn)
+HANDLE_MEMORY_STMT(16, AllocLocal,   AllocateLocalInsn)
+HANDLE_MEMORY_STMT(17, Load,         LoadInsn)
+HANDLE_MEMORY_STMT(18, Store,        StoreInsn)
+HANDLE_MEMORY_STMT(19, Disassociate, DisassociateInsn)
+LAST_MEMORY_STMT(19)
 
 // Other operators - These are operations that don't fit the above categories
-FIRST_OTHER_STMT(19)
-HANDLE_OTHER_STMT(19, Call,         CallStmt)
-HANDLE_OTHER_STMT(20, RTCall,       RuntimeStmt)
-HANDLE_OTHER_STMT(21, IORTCall,     IORuntimeStmt)
-HANDLE_OTHER_STMT(22, ScopeEnt,     ScopeEnterStmt)
-HANDLE_OTHER_STMT(23, ScopeExt,     ScopeExitStmt)
-HANDLE_LAST_OTHER_STMT(24, PHI,     PHIStmt)
-LAST_OTHER_STMT(24)
+FIRST_OTHER_STMT(20)
+HANDLE_OTHER_STMT(20, Call,          CallStmt)
+HANDLE_OTHER_STMT(21, RuntimeCall,   RuntimeStmt)
+HANDLE_OTHER_STMT(22, IORuntimeCall, IORuntimeStmt)
+HANDLE_OTHER_STMT(23, ScopeEnter,    ScopeEnterStmt)
+HANDLE_OTHER_STMT(24, ScopeExit,     ScopeExitStmt)
+HANDLE_LAST_OTHER_STMT(25, Phi,      PHIStmt)
+LAST_OTHER_STMT(25)
 
 #undef FIRST_TERM_STMT
 #undef HANDLE_TERM_STMT
index f2e29cc..38f8642 100644 (file)
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "stmt.h"
+#include "statements.h"
 
 namespace Fortran::FIR {
 
@@ -172,10 +172,17 @@ std::string Statement::dump() const {
           [](const SwitchStmt &switchStatement) {
             return "switch("s + switchStatement.getCond().dump() + ")"s;
           },
-          [](const IndirectBrStmt &) { return "ibranch"s; },
+          [](const SwitchCaseStmt &switchCaseStmt) {
+            return "switch-case("s + switchCaseStmt.getCond().dump() + ")"s;
+          },
+          [](const SwitchTypeStmt &switchTypeStmt) {
+            return "switch-type("s + switchTypeStmt.getCond().dump() + ")"s;
+          },
+          [](const SwitchRankStmt &switchRankStmt) {
+            return "switch-rank("s + switchRankStmt.getCond().dump() + ")"s;
+          },
+          [](const IndirectBranchStmt &) { return "ibranch"s; },
           [](const UnreachableStmt &) { return "unreachable"s; },
-          [](const AllocateStmt &) { return "alloc"s; },
-          [](const DeallocateStmt &) { return "dealloc"s; },
           [](const AssignmentStmt &assignmentStatement) {
             auto computedValue{
                 FIR::dump(assignmentStatement.GetRightHandSide())};
@@ -190,7 +197,6 @@ std::string Statement::dump() const {
             return "assign &("s + computedAddress + ") to "s + address;
           },
           [](const LabelAssignStmt &) { return "lblassn"s; },
-          [](const DisassociateStmt &) { return "NULLIFY"s; },
           [](const ApplyExprStmt &applyExpression) {
             return std::visit(
                 common::visitors{
@@ -217,24 +223,19 @@ std::string Statement::dump() const {
                 },
                 applyExpression.u);
           },
-          [](const ScopeEnterStmt &) { return "scopeenter"s; },
-          [](const ScopeExitStmt &) { return "scopeexit"s; },
-          [](const PHIStmt &) { return "PHI"s; },
+          [](const LocateExprStmt &) { return "locate"s; },
+          [](const AllocateInsn &) { return "alloc"s; },
+          [](const DeallocateInsn &) { return "dealloc"s; },
+          [](const AllocateLocalInsn &) { return "alloca"s; },
+          [](const LoadInsn &) { return "load"s; },
+          [](const StoreInsn &) { return "store"s; },
+          [](const DisassociateInsn &) { return "NULLIFY"s; },
           [](const CallStmt &) { return "call"s; },
           [](const RuntimeStmt &) { return "runtime-call()"s; },
           [](const IORuntimeStmt &) { return "io-call()"s; },
-          [](const SwitchCaseStmt &switchCaseStmt) {
-            return "switch-case("s + switchCaseStmt.getCond().dump() + ")"s;
-          },
-          [](const SwitchTypeStmt &switchTypeStmt) {
-            return "switch-type("s + switchTypeStmt.getCond().dump() + ")"s;
-          },
-          [](const SwitchRankStmt &switchRankStmt) {
-            return "switch-rank("s + switchRankStmt.getCond().dump() + ")"s;
-          },
-          [](const AllocLocalInsn &) { return "alloca"s; },
-          [](const LoadInsn &) { return "load"s; },
-          [](const StoreInsn &) { return "store"s; },
+          [](const ScopeEnterStmt &) { return "scopeenter"s; },
+          [](const ScopeExitStmt &) { return "scopeexit"s; },
+          [](const PHIStmt &) { return "PHI"s; },
       },
       u);
 }
index 8005259..ace21f8 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef FORTRAN_FIR_STATEMENTS_H_
 #define FORTRAN_FIR_STATEMENTS_H_
 
+#include "basicblock.h"
 #include "common.h"
 #include "mixin.h"
 #include <initializer_list>
 
 namespace Fortran::FIR {
 
-#define HANDLE_STMT(num, opcode, name) struct name;
-#include "statement.def"
+class ReturnStmt;
+class BranchStmt;
+class SwitchStmt;
+class SwitchCaseStmt;
+class SwitchTypeStmt;
+class SwitchRankStmt;
+class IndirectBranchStmt;
+class UnreachableStmt;
+class AssignmentStmt;
+class PointerAssignStmt;
+class LabelAssignStmt;
+class ApplyExprStmt;
+class LocateExprStmt;
+class AllocateInsn;
+class DeallocateInsn;
+class AllocateLocalInsn;
+class LoadInsn;
+class StoreInsn;
+class DisassociateInsn;
+class CallStmt;
+class RuntimeStmt;
+class IORuntimeStmt;
+class ScopeEnterStmt;
+class ScopeExitStmt;
+class PHIStmt;
 
 class Statement;
 
@@ -47,16 +71,19 @@ public:
   std::string dump() const;
 };
 
-struct Stmt_impl {
+class Stmt_impl {
+public:
   using StatementTrait = std::true_type;
 };
 
-struct TerminatorStmt_impl : public Stmt_impl {
+class TerminatorStmt_impl : public Stmt_impl {
+public:
   virtual std::list<BasicBlock *> succ_blocks() const { return {}; }
   using TerminatorTrait = std::true_type;
 };
 
-struct ReturnStmt : public TerminatorStmt_impl {
+class ReturnStmt : public TerminatorStmt_impl {
+public:
   static ReturnStmt Create() { return ReturnStmt{nullptr}; }
   static ReturnStmt Create(Expression *expression) {
     return ReturnStmt{expression};
@@ -67,7 +94,8 @@ private:
   explicit ReturnStmt(Expression *);
 };
 
-struct BranchStmt : public TerminatorStmt_impl {
+class BranchStmt : public TerminatorStmt_impl {
+public:
   static BranchStmt Create(
       Expression *condition, BasicBlock *trueBlock, BasicBlock *falseBlock) {
     return BranchStmt{condition, trueBlock, falseBlock};
@@ -96,7 +124,8 @@ private:
 };
 
 /// Switch on an expression into a set of constant values
-struct SwitchStmt : public TerminatorStmt_impl {
+class SwitchStmt : public TerminatorStmt_impl {
+public:
   using ValueType = Expression *;
   using ValueSuccPairType = std::pair<ValueType, BasicBlock *>;
   using ValueSuccPairListType = std::vector<ValueSuccPairType>;
@@ -116,7 +145,8 @@ private:
 };
 
 /// Switch on an expression into a set of value (open or closed) ranges
-struct SwitchCaseStmt : public TerminatorStmt_impl {
+class SwitchCaseStmt : public TerminatorStmt_impl {
+public:
   struct Default {};
   struct Exactly {  // selector == v
     Expression *v;
@@ -152,9 +182,9 @@ private:
   ValueSuccPairListType valueSuccPairs_;
 };
 
-using Type = const semantics::DeclTypeSpec *;  // FIXME
 /// Switch on the TYPE of the selector into a set of TYPES, etc.
-struct SwitchTypeStmt : public TerminatorStmt_impl {
+class SwitchTypeStmt : public TerminatorStmt_impl {
+public:
   struct Default {};
   struct TypeSpec {
     Type v;
@@ -181,7 +211,8 @@ private:
 };
 
 /// Switch on the RANK of the selector into a set of constant integers, etc.
-struct SwitchRankStmt : public TerminatorStmt_impl {
+class SwitchRankStmt : public TerminatorStmt_impl {
+public:
   struct Default {};  // RANK DEFAULT
   struct AssumedSize {};  // RANK(*)
   struct Exactly {  // RANK(n)
@@ -205,29 +236,33 @@ private:
   ValueSuccPairListType valueSuccPairs_;
 };
 
-struct IndirectBrStmt : public TerminatorStmt_impl {
+class IndirectBranchStmt : public TerminatorStmt_impl {
+public:
   using TargetListType = std::vector<BasicBlock *>;
-  static IndirectBrStmt Create(
+  static IndirectBranchStmt Create(
       Variable *variable, const TargetListType &potentialTargets) {
-    return IndirectBrStmt{variable, potentialTargets};
+    return IndirectBranchStmt{variable, potentialTargets};
   }
 
 private:
-  explicit IndirectBrStmt(
+  explicit IndirectBranchStmt(
       Variable *variable, const TargetListType &potentialTargets)
     : variable_{variable}, potentialTargets_{potentialTargets} {}
   Variable *variable_;
   TargetListType potentialTargets_;
 };
 
-struct UnreachableStmt : public TerminatorStmt_impl {
+/// This statement is not reachable
+class UnreachableStmt : public TerminatorStmt_impl {
+public:
   static UnreachableStmt Create() { return UnreachableStmt{}; }
 
 private:
   explicit UnreachableStmt() = default;
 };
 
-struct ActionStmt_impl : public Stmt_impl {
+class ActionStmt_impl : public Stmt_impl {
+public:
   using ActionTrait = std::true_type;
 
 protected:
@@ -237,7 +272,8 @@ protected:
   std::optional<evaluate::DynamicType> type;
 };
 
-struct AssignmentStmt : public ActionStmt_impl {
+class AssignmentStmt : public ActionStmt_impl {
+public:
   static AssignmentStmt Create(const PathVariable *lhs, const Expression *rhs) {
     return AssignmentStmt{lhs, rhs};
   }
@@ -252,7 +288,8 @@ private:
   const Expression *rhs_;
 };
 
-struct PointerAssignStmt : public ActionStmt_impl {
+class PointerAssignStmt : public ActionStmt_impl {
+public:
   static PointerAssignStmt Create(
       const Expression *lhs, const Expression *rhs) {
     return PointerAssignStmt{lhs, rhs};
@@ -268,7 +305,8 @@ private:
   const Expression *rhs_;
 };
 
-struct LabelAssignStmt : public ActionStmt_impl {
+class LabelAssignStmt : public ActionStmt_impl {
+public:
   static LabelAssignStmt Create(const semantics::Symbol *lhs, BasicBlock *rhs) {
     return LabelAssignStmt{lhs, rhs};
   }
@@ -281,100 +319,123 @@ private:
   BasicBlock *rhs_;
 };
 
-struct MemoryStmt_impl : public ActionStmt_impl {
+/// Compute the value of an expression
+class ApplyExprStmt
+  : public ActionStmt_impl,
+    public SumTypeCopyMixin<std::variant<const parser::AssociateStmt *,
+        const parser::ChangeTeamStmt *, const parser::NonLabelDoStmt *,
+        const parser::ForallConstructStmt *, const Expression *>> {
+public:
+  template<typename T> static ApplyExprStmt Create(const T *e) {
+    return ApplyExprStmt{e};
+  }
+
+private:
+  template<typename T>
+  explicit ApplyExprStmt(const T *e) : SumTypeCopyMixin{e} {}
+  // Evaluation evaluation_;
+};
+
+/// Compute the location of an expression
+class LocateExprStmt : public ActionStmt_impl {
+public:
+  static LocateExprStmt *Create(const Expression *e) {
+    return new LocateExprStmt(e);
+  }
+
+private:
+  explicit LocateExprStmt(const Expression *e) : expression_{e} {}
+  const Expression *expression_;
+};
+
+class MemoryStmt_impl : public ActionStmt_impl {
+public:
   // FIXME: ought to use a Type, let backend compute size...
 protected:
   MemoryStmt_impl() {}
 };
 
-/// ALLOCATE allocate space for a pointer target or allocatable and populate the
-/// reference
-struct AllocateStmt : public MemoryStmt_impl {
-  static AllocateStmt Create(const Expression *object) {
-    return AllocateStmt{object};
+/// Allocate storage on the heap
+class AllocateInsn : public MemoryStmt_impl {
+public:
+  static AllocateInsn Create(Type type, int alignment = 0) {
+    return AllocateInsn{type, alignment};
   }
 
 private:
-  explicit AllocateStmt(const Expression *object) : object_{object} {}
-  const Expression *object_;  // POINTER|ALLOCATABLE to be allocated
-  // TODO: maybe add other arguments
+  explicit AllocateInsn(Type type, int alignment)
+    : type_{type}, alignment_{alignment} {}
+
+  Type type_;
+  int alignment_;
 };
 
-/// DEALLOCATE deallocate allocatable variables and pointer targets. pointers
-/// become disassociated
-struct DeallocateStmt : public MemoryStmt_impl {
-  static DeallocateStmt Create(const Expression *object) {
-    return DeallocateStmt{object};
+/// Deallocate storage on the heap
+class DeallocateInsn : public MemoryStmt_impl {
+public:
+  static DeallocateInsn Create(const AllocateInsn *alloc) {
+    return DeallocateInsn{alloc};
   }
 
 private:
-  explicit DeallocateStmt(const Expression *object) : object_{object} {}
-  const Expression *object_;  // POINTER|ALLOCATABLE to be deallocated
-  // TODO: maybe add other arguments
+  explicit DeallocateInsn(const AllocateInsn *alloc) : alloc_{alloc} {}
+  const AllocateInsn *alloc_;
 };
 
-struct AllocLocalInsn : public MemoryStmt_impl {
-  static AllocLocalInsn Create(Type type, unsigned alignment = 0u) {
-    return AllocLocalInsn{type, alignment};
+/// Allocate space for a varible by its Type. This storage's lifetime will not
+/// exceed that of the containing Procedure.
+class AllocateLocalInsn : public MemoryStmt_impl {
+public:
+  static AllocateLocalInsn Create(Type type, int alignment = 0) {
+    return AllocateLocalInsn{type, alignment};
   }
 
 private:
-  explicit AllocLocalInsn(Type type, unsigned alignment)
-    : alignment_{alignment} {}
-  unsigned alignment_;
+  explicit AllocateLocalInsn(Type type, int alignment)
+    : type_{type}, alignment_{alignment} {}
+  Type type_;
+  int alignment_;
 };
 
-struct LoadInsn : public MemoryStmt_impl {
-  static LoadInsn Create(const Expression *address) {
-    return LoadInsn{address};
-  }
+/// Load value(s) from a location
+class LoadInsn : public MemoryStmt_impl {
+public:
+  static LoadInsn Create(Value *address) { return LoadInsn{address}; }
 
 private:
-  explicit LoadInsn(const Expression *address) : address_{address} {}
-  const Expression *address_;
+  explicit LoadInsn(Value *address) : address_{address} {}
+  Value *address_;
 };
 
-struct StoreInsn : public MemoryStmt_impl {
-  static StoreInsn Create(const Expression *address, const Expression *value) {
+/// Store value(s) from an applied expression to a location
+class StoreInsn : public MemoryStmt_impl {
+public:
+  static StoreInsn Create(Value *address, const Expression *value) {
     return StoreInsn{address, value};
   }
 
 private:
-  explicit StoreInsn(const Expression *address, const Expression *value)
+  explicit StoreInsn(Value *address, const Expression *value)
     : address_{address}, value_{value} {}
-  const Expression *address_;
+  Value *address_;
   const Expression *value_;
 };
 
-/// NULLIFY make pointer object disassociated
-struct DisassociateStmt : public ActionStmt_impl {
-  static DisassociateStmt Create(const parser::NullifyStmt *n) {
-    return DisassociateStmt{n};
+/// NULLIFY - make pointer object disassociated
+class DisassociateInsn : public ActionStmt_impl {
+public:
+  static DisassociateInsn Create(const parser::NullifyStmt *n) {
+    return DisassociateInsn{n};
   }
 
 private:
-  DisassociateStmt(const parser::NullifyStmt *n) : disassociate_{n} {}
+  DisassociateInsn(const parser::NullifyStmt *n) : disassociate_{n} {}
   const parser::NullifyStmt *disassociate_;
 };
 
-/// expressions that must be evaluated in various statements
-struct ApplyExprStmt
-  : public ActionStmt_impl,
-    public SumTypeCopyMixin<std::variant<const parser::AssociateStmt *,
-        const parser::ChangeTeamStmt *, const parser::NonLabelDoStmt *,
-        const parser::ForallConstructStmt *, const Expression *>> {
-  template<typename T> static ApplyExprStmt Create(const T *e) {
-    return ApplyExprStmt{e};
-  }
-
-private:
-  template<typename T>
-  explicit ApplyExprStmt(const T *e) : SumTypeCopyMixin{e} {}
-  // Evaluation evaluation_;
-};
-
 /// base class for all call-like IR statements
-struct CallStmt_impl : public ActionStmt_impl {
+class CallStmt_impl : public ActionStmt_impl {
+public:
   const Value *Callee() const { return callee_; }
   unsigned NumArgs() const { return arguments_.size(); }
 
@@ -389,7 +450,10 @@ protected:
 };
 
 /// CALL statements and function references
-struct CallStmt : public CallStmt_impl {
+/// A CallStmt has pass-by-value semantics. Pass-by-reference must be done
+/// explicitly by passing addresses of objects or temporaries.
+class CallStmt : public CallStmt_impl {
+public:
   static CallStmt Create(const FunctionType *type, const Value *callee,
       CallArguments &&arguments) {
     return CallStmt{type, callee, std::move(arguments)};
@@ -402,7 +466,8 @@ private:
 };
 
 /// Miscellaneous statements that turn into runtime calls
-struct RuntimeStmt : public CallStmt_impl {
+class RuntimeStmt : public CallStmt_impl {
+public:
   static RuntimeStmt Create(
       RuntimeCallType call, RuntimeCallArguments &&argument) {
     return RuntimeStmt{call, std::move(argument)};
@@ -417,7 +482,8 @@ private:
 
 /// The 13 Fortran I/O statements. Will be lowered to whatever becomes of the
 /// I/O runtime.
-struct IORuntimeStmt : public CallStmt_impl {
+class IORuntimeStmt : public CallStmt_impl {
+public:
   static IORuntimeStmt Create(
       InputOutputCallType call, IOCallArguments &&arguments) {
     return IORuntimeStmt{call, std::move(arguments)};
@@ -430,7 +496,8 @@ private:
   InputOutputCallType call_;
 };
 
-struct ScopeStmt_impl : public ActionStmt_impl {
+class ScopeStmt_impl : public ActionStmt_impl {
+public:
   Scope *GetScope() const { return scope; }
 
 protected:
@@ -439,7 +506,8 @@ protected:
 };
 
 /// From the CFG document
-struct ScopeEnterStmt : public ScopeStmt_impl {
+class ScopeEnterStmt : public ScopeStmt_impl {
+public:
   static ScopeEnterStmt Create(Scope *scope) { return ScopeEnterStmt{scope}; }
 
 private:
@@ -447,7 +515,8 @@ private:
 };
 
 /// From the CFG document
-struct ScopeExitStmt : public ScopeStmt_impl {
+class ScopeExitStmt : public ScopeStmt_impl {
+public:
   static ScopeExitStmt Create(Scope *scope) { return ScopeExitStmt{scope}; }
 
 private:
@@ -455,7 +524,8 @@ private:
 };
 
 /// From the CFG document to support SSA
-struct PHIStmt : public ActionStmt_impl {
+class PHIStmt : public ActionStmt_impl {
+public:
   static PHIStmt Create(unsigned numReservedValues) {
     return PHIStmt{numReservedValues};
   }
@@ -465,6 +535,53 @@ private:
 
   std::vector<PHIPair> inputs_;
 };
+
+/// Sum type over all statement classes
+class Statement : public SumTypeMixin<std::variant<ReturnStmt,  //
+                      BranchStmt,  //
+                      SwitchStmt,  //
+                      SwitchCaseStmt,  //
+                      SwitchTypeStmt,  //
+                      SwitchRankStmt,  //
+                      IndirectBranchStmt,  //
+                      UnreachableStmt,  //
+                      AssignmentStmt,  //
+                      PointerAssignStmt,  //
+                      LabelAssignStmt,  //
+                      ApplyExprStmt,  //
+                      LocateExprStmt,  //
+                      AllocateInsn,  //
+                      DeallocateInsn,  //
+                      AllocateLocalInsn,  //
+                      LoadInsn,  //
+                      StoreInsn,  //
+                      DisassociateInsn,  //
+                      CallStmt,  //
+                      RuntimeStmt,  //
+                      IORuntimeStmt,  //
+                      ScopeEnterStmt,  //
+                      ScopeExitStmt,  //
+                      PHIStmt  //
+                      >>,
+                  public ChildMixin<Statement, BasicBlock>,
+                  public llvm::ilist_node<Statement> {
+public:
+  template<typename A>
+  Statement(BasicBlock *p, A &&t) : SumTypeMixin{t}, ChildMixin{p} {
+    parent->insertBefore(this);
+  }
+  std::string dump() const;
+};
+
+inline std::list<BasicBlock *> succ_list(BasicBlock &block) {
+  if (auto *terminator{block.getTerminator()}) {
+    return reinterpret_cast<const TerminatorStmt_impl *>(&terminator->u)
+        ->succ_blocks();
+  }
+  // CHECK(false && "block does not have terminator");
+  return {};
+}
+
 }
 
-#endif
+#endif  // FORTRAN_FIR_STATEMENTS_H_