[flang] revert last pushes
authorEric Schweitz <eschweitz@nvidia.com>
Wed, 24 Apr 2019 18:41:40 +0000 (11:41 -0700)
committerEric Schweitz <eschweitz@nvidia.com>
Wed, 24 Apr 2019 18:41:40 +0000 (11:41 -0700)
Original-commit: flang-compiler/f18@39335746a99c5291b82932f119bc2d25d251f022

flang/lib/CMakeLists.txt
flang/lib/FIR/afforestation.cc
flang/lib/FIR/builder.h
flang/lib/FIR/statements.h
flang/lib/bridge/CMakeLists.txt [deleted file]
flang/lib/bridge/ir-gen.cc [deleted file]
flang/lib/bridge/ir-gen.h [deleted file]

index a0f33da..660506e 100644 (file)
@@ -17,4 +17,3 @@ add_subdirectory(evaluate)
 add_subdirectory(FIR)
 add_subdirectory(parser)
 add_subdirectory(semantics)
-add_subdirectory(bridge)
index f5a18ef..a584cba 100644 (file)
 
 namespace Fortran::FIR {
 namespace {
-Expression *ExprRef(const parser::Expr &a) {
+const Expression &ExprRef(const parser::Expr &a) {
   CHECK(a.typedExpr);
   CHECK(a.typedExpr->v);
-  return &*a.typedExpr->v;
+  return *a.typedExpr->v;
 }
-Expression *ExprRef(const common::Indirection<parser::Expr> &a) {
+const Expression &ExprRef(const common::Indirection<parser::Expr> &a) {
   return ExprRef(a.value());
 }
+const Expression &ExprRef(const parser::Variable &a) {
+  CHECK(a.typedExpr);
+  CHECK(a.typedExpr->v);
+  return *a.typedExpr->v;
+}
 
 template<typename STMTTYPE, typename CT>
 const std::optional<parser::Name> &GetSwitchAssociateName(
@@ -141,7 +146,7 @@ static std::vector<SwitchRankStmt::ValueType> populateSwitchValues(
         common::visitors{
             [&](const parser::ScalarIntConstantExpr &exp) {
               const auto &e{exp.thing.thing.thing.value()};
-              result.emplace_back(SwitchRankStmt::Exactly{ExprRef(e)});
+              result.emplace_back(SwitchRankStmt::Exactly{&ExprRef(e)});
             },
             [&](const parser::Star &) {
               result.emplace_back(SwitchRankStmt::AssumedSize{});
@@ -416,48 +421,109 @@ public:
 
   // IO argument translations ...
   IOCallArguments CreateBackspaceArguments(
-      const std::list<parser::PositionOrFlushSpec> &);
+      const std::list<parser::PositionOrFlushSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateCloseArguments(
-      const std::list<parser::CloseStmt::CloseSpec> &);
+      const std::list<parser::CloseStmt::CloseSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateEndfileArguments(
-      const std::list<parser::PositionOrFlushSpec> &);
+      const std::list<parser::PositionOrFlushSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateFlushArguments(
-      const std::list<parser::PositionOrFlushSpec> &);
+      const std::list<parser::PositionOrFlushSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateRewindArguments(
-      const std::list<parser::PositionOrFlushSpec> &);
+      const std::list<parser::PositionOrFlushSpec> &specifiers) {
+    return IOCallArguments{};
+  }
+  IOCallArguments CreateInquireArguments(
+      const std::list<parser::InquireSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateInquireArguments(
-      const std::list<parser::InquireSpec> &);
-  IOCallArguments CreateInquireArguments(const parser::InquireStmt::Iolength &);
-  IOCallArguments CreateOpenArguments(const std::list<parser::ConnectSpec> &);
-  IOCallArguments CreateWaitArguments(const std::list<parser::WaitSpec> &);
+      const parser::InquireStmt::Iolength &iolength) {
+    return IOCallArguments{};
+  }
+  IOCallArguments CreateOpenArguments(
+      const std::list<parser::ConnectSpec> &specifiers) {
+    return IOCallArguments{};
+  }
+  IOCallArguments CreateWaitArguments(
+      const std::list<parser::WaitSpec> &specifiers) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreatePrintArguments(const parser::Format &format,
-      const std::list<parser::OutputItem> &outputs);
+      const std::list<parser::OutputItem> &outputs) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateReadArguments(
       const std::optional<parser::IoUnit> &ioUnit,
       const std::optional<parser::Format> &format,
       const std::list<parser::IoControlSpec> &controls,
-      const std::list<parser::InputItem> &inputs);
+      const std::list<parser::InputItem> &inputs) {
+    return IOCallArguments{};
+  }
   IOCallArguments CreateWriteArguments(
       const std::optional<parser::IoUnit> &ioUnit,
       const std::optional<parser::Format> &format,
       const std::list<parser::IoControlSpec> &controls,
-      const std::list<parser::OutputItem> &outputs);
-
-  // Image related runtime argument translations ...
-  RuntimeCallArguments CreateEventPostArguments(const parser::EventPostStmt &);
-  RuntimeCallArguments CreateEventWaitArguments(const parser::EventWaitStmt &);
-  RuntimeCallArguments CreateFailImageArguments(const parser::FailImageStmt &);
-  RuntimeCallArguments CreateFormTeamArguments(const parser::FormTeamStmt &);
-  RuntimeCallArguments CreateLockArguments(const parser::LockStmt &);
-  RuntimeCallArguments CreatePauseArguments(const parser::PauseStmt &);
-  RuntimeCallArguments CreateStopArguments(const parser::StopStmt &);
-  RuntimeCallArguments CreateSyncAllArguments(const parser::SyncAllStmt &);
+      const std::list<parser::OutputItem> &outputs) {
+    return IOCallArguments{};
+  }
+
+  // Runtime argument translations ...
+  RuntimeCallArguments CreateEventPostArguments(
+      const parser::EventPostStmt &eventPostStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateEventWaitArguments(
+      const parser::EventWaitStmt &eventWaitStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateFailImageArguments(
+      const parser::FailImageStmt &failImageStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateFormTeamArguments(
+      const parser::FormTeamStmt &formTeamStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateLockArguments(
+      const parser::LockStmt &lockStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreatePauseArguments(
+      const parser::PauseStmt &pauseStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateStopArguments(
+      const parser::StopStmt &stopStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateSyncAllArguments(
+      const parser::SyncAllStmt &syncAllStatement) {
+    return RuntimeCallArguments{};
+  }
   RuntimeCallArguments CreateSyncImagesArguments(
-      const parser::SyncImagesStmt &);
+      const parser::SyncImagesStmt &syncImagesStatement) {
+    return RuntimeCallArguments{};
+  }
   RuntimeCallArguments CreateSyncMemoryArguments(
-      const parser::SyncMemoryStmt &);
-  RuntimeCallArguments CreateSyncTeamArguments(const parser::SyncTeamStmt &);
-  RuntimeCallArguments CreateUnlockArguments(const parser::UnlockStmt &);
+      const parser::SyncMemoryStmt &syncMemoryStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateSyncTeamArguments(
+      const parser::SyncTeamStmt &syncTeamStatement) {
+    return RuntimeCallArguments{};
+  }
+  RuntimeCallArguments CreateUnlockArguments(
+      const parser::UnlockStmt &unlockStatement) {
+    return RuntimeCallArguments{};
+  }
 
   // CALL translations ...
   const Value CreateCalleeValue(const parser::ProcedureDesignator &designator) {
@@ -476,7 +542,7 @@ public:
               return builder_->CreateExpr(ExprRef(e));
             },
             [&](const parser::Variable &v) {
-              return builder_->CreateExpr(ToExpression(v));
+              return builder_->CreateExpr(ExprRef(v));
             },
         },
         std::get<parser::Selector>(
@@ -571,7 +637,7 @@ public:
     // TODO: check if allocation or reallocation should happen, etc.
     auto *value{builder_->CreateExpr(ExprRef(std::get<parser::Expr>(stmt.t)))};
     auto addr{
-        builder_->CreateAddr(ToExpression(std::get<parser::Variable>(stmt.t)))};
+        builder_->CreateAddr(ExprRef(std::get<parser::Variable>(stmt.t)))};
     builder_->CreateStore(addr, value);
   }
   void handleDefinedAssignmentStmt(const parser::AssignmentStmt &stmt) {
@@ -599,10 +665,10 @@ public:
       std::visit(
           common::visitors{
               [&](const parser::AllocOpt::Mold &m) {
-                opts.mold = *ExprRef(m.v);
+                opts.mold = ExprRef(m.v);
               },
               [&](const parser::AllocOpt::Source &s) {
-                opts.source = *ExprRef(s.v);
+                opts.source = ExprRef(s.v);
               },
               [&](const parser::StatOrErrmsg &var) {
                 std::visit(
@@ -627,8 +693,191 @@ public:
   }
 
   void handleActionStatement(
-      AnalysisData &ad, const parser::Statement<parser::ActionStmt> &stmt);
-
+      AnalysisData &ad, const parser::Statement<parser::ActionStmt> &stmt) {
+    std::visit(
+        common::visitors{
+            [&](const common::Indirection<parser::AllocateStmt> &s) {
+              handleAllocateStmt(s.value());
+            },
+            [&](const common::Indirection<parser::AssignmentStmt> &s) {
+              handleAssignmentStmt(s.value());
+            },
+            [&](const common::Indirection<parser::BackspaceStmt> &s) {
+              builder_->CreateIOCall(InputOutputCallBackspace,
+                  CreateBackspaceArguments(s.value().v));
+            },
+            [&](const common::Indirection<parser::CallStmt> &s) {
+              builder_->CreateCall(nullptr,
+                  CreateCalleeValue(
+                      std::get<parser::ProcedureDesignator>(s.value().v.t)),
+                  CreateCallArguments(
+                      std::get<std::list<parser::ActualArgSpec>>(
+                          s.value().v.t)));
+            },
+            [&](const common::Indirection<parser::CloseStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallClose, CreateCloseArguments(s.value().v));
+            },
+            [](const parser::ContinueStmt &) { WRONG_PATH(); },
+            [](const common::Indirection<parser::CycleStmt> &) {
+              WRONG_PATH();
+            },
+            [&](const common::Indirection<parser::DeallocateStmt> &s) {
+              for (auto &alloc :
+                  std::get<std::list<parser::AllocateObject>>(s.value().t)) {
+                builder_->CreateDealloc(
+                    CreateDeallocationValue(&alloc, &s.value()));
+              }
+            },
+            [&](const common::Indirection<parser::EndfileStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallEndfile, CreateEndfileArguments(s.value().v));
+            },
+            [&](const common::Indirection<parser::EventPostStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallEventPost, CreateEventPostArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::EventWaitStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallEventWait, CreateEventWaitArguments(s.value()));
+            },
+            [](const common::Indirection<parser::ExitStmt> &) { WRONG_PATH(); },
+            [&](const parser::FailImageStmt &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallFailImage, CreateFailImageArguments(s));
+            },
+            [&](const common::Indirection<parser::FlushStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallFlush, CreateFlushArguments(s.value().v));
+            },
+            [&](const common::Indirection<parser::FormTeamStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallFormTeam, CreateFormTeamArguments(s.value()));
+            },
+            [](const common::Indirection<parser::GotoStmt> &) { WRONG_PATH(); },
+            [](const common::Indirection<parser::IfStmt> &) { WRONG_PATH(); },
+            [&](const common::Indirection<parser::InquireStmt> &s) {
+              std::visit(
+                  common::visitors{
+                      [&](const std::list<parser::InquireSpec> &specifiers) {
+                        builder_->CreateIOCall(InputOutputCallInquire,
+                            CreateInquireArguments(specifiers));
+                      },
+                      [&](const parser::InquireStmt::Iolength &iolength) {
+                        builder_->CreateIOCall(InputOutputCallInquire,
+                            CreateInquireArguments(iolength));
+                      },
+                  },
+                  s.value().u);
+            },
+            [&](const common::Indirection<parser::LockStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallLock, CreateLockArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::NullifyStmt> &s) {
+              for (auto &obj : s.value().v) {
+                std::visit(
+                    common::visitors{
+                        [&](const parser::Name &n) {
+                          auto s{builder_->CreateAddr(ToExpression(n))};
+                          builder_->CreateNullify(s);
+                        },
+                        [&](const parser::StructureComponent &sc) {
+                          auto s{builder_->CreateAddr(ToExpression(sc))};
+                          builder_->CreateNullify(s);
+                        },
+                    },
+                    obj.u);
+              }
+            },
+            [&](const common::Indirection<parser::OpenStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallOpen, CreateOpenArguments(s.value().v));
+            },
+            [&](const common::Indirection<parser::PointerAssignmentStmt> &s) {
+              auto *value{CreatePointerValue(s.value())};
+              auto addr{builder_->CreateAddr(
+                  ExprRef(std::get<parser::Expr>(s.value().t)))};
+              builder_->CreateStore(addr, value);
+            },
+            [&](const common::Indirection<parser::PrintStmt> &s) {
+              builder_->CreateIOCall(InputOutputCallPrint,
+                  CreatePrintArguments(std::get<parser::Format>(s.value().t),
+                      std::get<std::list<parser::OutputItem>>(s.value().t)));
+            },
+            [&](const common::Indirection<parser::ReadStmt> &s) {
+              builder_->CreateIOCall(InputOutputCallRead,
+                  CreateReadArguments(s.value().iounit, s.value().format,
+                      s.value().controls, s.value().items));
+            },
+            [](const common::Indirection<parser::ReturnStmt> &) {
+              WRONG_PATH();
+            },
+            [&](const common::Indirection<parser::RewindStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallRewind, CreateRewindArguments(s.value().v));
+            },
+            [&](const common::Indirection<parser::StopStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallStop, CreateStopArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::SyncAllStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallSyncAll, CreateSyncAllArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::SyncImagesStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallSyncImages, CreateSyncImagesArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::SyncMemoryStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallSyncMemory, CreateSyncMemoryArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::SyncTeamStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallSyncTeam, CreateSyncTeamArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::UnlockStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallUnlock, CreateUnlockArguments(s.value()));
+            },
+            [&](const common::Indirection<parser::WaitStmt> &s) {
+              builder_->CreateIOCall(
+                  InputOutputCallWait, CreateWaitArguments(s.value().v));
+            },
+            [](const common::Indirection<parser::WhereStmt> &) { /*fixme*/ },
+            [&](const common::Indirection<parser::WriteStmt> &s) {
+              builder_->CreateIOCall(InputOutputCallWrite,
+                  CreateWriteArguments(s.value().iounit, s.value().format,
+                      s.value().controls, s.value().items));
+            },
+            [](const common::Indirection<parser::ComputedGotoStmt> &) {
+              WRONG_PATH();
+            },
+            [](const common::Indirection<parser::ForallStmt> &) { /*fixme*/ },
+            [](const common::Indirection<parser::ArithmeticIfStmt> &) {
+              WRONG_PATH();
+            },
+            [&](const common::Indirection<parser::AssignStmt> &s) {
+              auto addr{builder_->CreateAddr(
+                  ToExpression(std::get<parser::Name>(s.value().t)))};
+              auto *block{blockMap_
+                              .find(flat::FetchLabel(
+                                  ad, std::get<parser::Label>(s.value().t))
+                                        .get())
+                              ->second};
+              builder_->CreateStore(addr, block);
+            },
+            [](const common::Indirection<parser::AssignedGotoStmt> &) {
+              WRONG_PATH();
+            },
+            [&](const common::Indirection<parser::PauseStmt> &s) {
+              builder_->CreateRuntimeCall(
+                  RuntimeCallPause, CreatePauseArguments(s.value()));
+            },
+        },
+        stmt.statement.u);
+  }
   void handleLinearAction(const flat::ActionOp &action, AnalysisData &ad) {
     handleActionStatement(ad, *action.v);
   }
@@ -683,20 +932,94 @@ public:
       if (info->stepExpr) {
         Expression compare{ConsExpr(common::RelationalOperator::GT,
             getLocalVariable(info->counter), CreateConstant(0))};
-        auto *cond{builder_->CreateExpr(&compare)};
+        auto *cond{builder_->CreateExpr(std::move(compare))};
         info->condition = cond;
       }
     }
   }
 
   // InitiateConstruct - many constructs require some initial setup
-  void InitiateConstruct(const parser::AssociateStmt *stmt);
-  void InitiateConstruct(const parser::SelectCaseStmt *stmt);
-  void InitiateConstruct(const parser::ChangeTeamStmt *stmt);
-  void InitiateConstruct(const parser::IfThenStmt *stmt);
-  void InitiateConstruct(const parser::WhereConstructStmt *stmt);
-  void InitiateConstruct(const parser::ForallConstructStmt *stmt);
-  void InitiateConstruct(const parser::NonLabelDoStmt *stmt);
+  void InitiateConstruct(const parser::AssociateStmt *stmt) {
+    for (auto &assoc : std::get<std::list<parser::Association>>(stmt->t)) {
+      auto &selector{std::get<parser::Selector>(assoc.t)};
+      auto *expr{builder_->CreateExpr(
+          std::visit([](const auto &x) { return ExprRef(x); }, selector.u))};
+      auto name{
+          builder_->CreateAddr(ToExpression(std::get<parser::Name>(assoc.t)))};
+      builder_->CreateStore(name, expr);
+    }
+  }
+  void InitiateConstruct(const parser::SelectCaseStmt *stmt) {
+    builder_->CreateExpr(
+        ExprRef(std::get<parser::Scalar<parser::Expr>>(stmt->t).thing));
+  }
+  void InitiateConstruct(const parser::ChangeTeamStmt *changeTeamStmt) {
+    // FIXME
+  }
+  void InitiateConstruct(const parser::IfThenStmt *ifThenStmt) {
+    const auto &e{std::get<parser::ScalarLogicalExpr>(ifThenStmt->t).thing};
+    builder_->CreateExpr(ExprRef(e.thing));
+  }
+  void InitiateConstruct(const parser::WhereConstructStmt *whereConstructStmt) {
+    const auto &e{std::get<parser::LogicalExpr>(whereConstructStmt->t)};
+    builder_->CreateExpr(ExprRef(e.thing));
+  }
+  void InitiateConstruct(
+      const parser::ForallConstructStmt *forallConstructStmt) {
+    // FIXME
+  }
+
+  void InitiateConstruct(const parser::NonLabelDoStmt *stmt) {
+    auto &ctrl{std::get<std::optional<parser::LoopControl>>(stmt->t)};
+    if (ctrl.has_value()) {
+      std::visit(
+          common::visitors{
+              [&](const parser::LoopBounds<parser::ScalarIntExpr> &bounds) {
+                auto name{builder_->CreateAddr(
+                    ToExpression(bounds.name.thing.thing))};
+                // evaluate e1, e2 [, e3] ...
+                auto *e1{
+                    builder_->CreateExpr(ExprRef(bounds.lower.thing.thing))};
+                auto *e2{
+                    builder_->CreateExpr(ExprRef(bounds.upper.thing.thing))};
+                Statement *e3;
+                if (bounds.step.has_value()) {
+                  e3 = builder_->CreateExpr(ExprRef(bounds.step->thing.thing));
+                } else {
+                  e3 = builder_->CreateExpr(CreateConstant(1));
+                }
+                // name <- e1
+                builder_->CreateStore(name, e1);
+                auto tripCounter{CreateTemp(GetDefaultIntegerType())};
+                // See 11.1.7.4.1, para. 1, item (3)
+                // totalTrips ::= iteration count = a
+                //   where a = (e2 - e1 + e3) / e3 if a > 0 and 0 otherwise
+                Expression tripExpr{ConsExpr<evaluate::Divide>(
+                    ConsExpr<evaluate::Add>(
+                        ConsExpr<evaluate::Subtract>(
+                            getApplyExpr(e2), getApplyExpr(e1)),
+                        getApplyExpr(e3)),
+                    getApplyExpr(e3))};
+                auto *totalTrips{builder_->CreateExpr(std::move(tripExpr))};
+                builder_->CreateStore(tripCounter, totalTrips);
+                PushDoContext(stmt, name, tripCounter, e3);
+              },
+              [&](const parser::ScalarLogicalExpr &expr) {
+                // See 11.1.7.4.1, para. 2
+                // See BuildLoopLatchExpression()
+                PushDoContext(stmt);
+              },
+              [&](const parser::LoopControl::Concurrent &cc) {
+                // See 11.1.7.4.2
+                // FIXME
+              },
+          },
+          ctrl->u);
+    } else {
+      // loop forever (See 11.1.7.4.1, para. 2)
+      PushDoContext(stmt);
+    }
+  }
 
   // finish DO construct construction
   void FinishConstruct(const parser::NonLabelDoStmt *stmt) {
@@ -718,8 +1041,7 @@ public:
                 return doMap_.find(stmt)->second.condition;
               },
               [&](const parser::ScalarLogicalExpr &sle) {
-                auto &exp{sle.thing.thing.value()};
-                SEMANTICS_CHECK(ExprRef(exp), "DO WHILE condition missing");
+                const auto &exp{sle.thing.thing};
                 return builder_->CreateExpr(ExprRef(exp));
               },
               [&](const parser::LoopControl::Concurrent &concurrent) {
@@ -735,14 +1057,273 @@ public:
   template<typename SWITCHTYPE, typename F>
   void AddOrQueueSwitch(Value condition,
       const std::vector<typename SWITCHTYPE::ValueType> &values,
-      const std::vector<flat::LabelRef> &labels, F function);
-  void AddOrQueueBranch(flat::LabelRef dest);
-  void AddOrQueueCGoto(Statement *condition, flat::LabelRef trueBlock,
-      flat::LabelRef falseBlock);
-  void AddOrQueueIGoto(AnalysisData &ad, const semantics::Symbol *symbol,
-      const std::vector<flat::LabelRef> &labels);
+      const std::vector<flat::LabelRef> &labels, F function) {
+    auto defer{false};
+    typename SWITCHTYPE::ValueSuccPairListType cases;
+    CHECK(values.size() == labels.size());
+    auto valiter{values.begin()};
+    for (auto lab : labels) {
+      auto labIter{blockMap_.find(lab)};
+      if (labIter == blockMap_.end()) {
+        defer = true;
+        break;
+      } else {
+        cases.emplace_back(*valiter++, labIter->second);
+      }
+    }
+    if (defer) {
+      using namespace std::placeholders;
+      controlFlowEdgesToAdd_.emplace_back(std::bind(
+          [](FIRBuilder *builder, BasicBlock *block, Value expr,
+              const std::vector<typename SWITCHTYPE::ValueType> &values,
+              const std::vector<flat::LabelRef> &labels, F function,
+              const LabelMapType &map) {
+            builder->SetInsertionPoint(block);
+            typename SWITCHTYPE::ValueSuccPairListType cases;
+            auto valiter{values.begin()};
+            for (auto &lab : labels) {
+              cases.emplace_back(*valiter++, map.find(lab)->second);
+            }
+            function(builder, expr, cases);
+          },
+          builder_, builder_->GetInsertionPoint(), condition, values, labels,
+          function, _1));
+    } else {
+      function(builder_, condition, cases);
+    }
+  }
 
-  void ConstructFIR(AnalysisData &ad);
+  void ConstructFIR(AnalysisData &ad) {
+    for (auto iter{linearOperations_.begin()}, iend{linearOperations_.end()};
+         iter != iend; ++iter) {
+      const auto &op{*iter};
+      std::visit(
+          common::visitors{
+              [&](const flat::LabelOp &op) {
+                auto *newBlock{CreateBlock(builder_->GetCurrentRegion())};
+                blockMap_.insert({op.get(), newBlock});
+                if (builder_->GetInsertionPoint()) {
+                  builder_->CreateBranch(newBlock);
+                }
+                builder_->SetInsertionPoint(newBlock);
+              },
+              [&](const flat::GotoOp &op) {
+                CheckInsertionPoint();
+                AddOrQueueBranch(op.target);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::IndirectGotoOp &op) {
+                CheckInsertionPoint();
+                AddOrQueueIGoto(ad, op.symbol, op.labelRefs);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::ReturnOp &op) {
+                CheckInsertionPoint();
+                std::visit(
+                    common::visitors{
+                        [&](const parser::FailImageStmt *s) {
+                          builder_->CreateRuntimeCall(RuntimeCallFailImage,
+                              CreateFailImageArguments(*s));
+                          builder_->CreateUnreachable();
+                        },
+                        [&](const parser::ReturnStmt *s) {
+                          // alt-return
+                          if (s->v) {
+                            const auto &exp{ExprRef(s->v->thing.thing)};
+                            auto app{builder_->QualifiedCreateExpr(exp)};
+                            builder_->CreateReturn(app);
+                          } else {
+                            auto zero{builder_->QualifiedCreateExpr(
+                                CreateConstant(0))};
+                            builder_->CreateReturn(zero);
+                          }
+                        },
+                        [&](const parser::StopStmt *s) {
+                          builder_->CreateRuntimeCall(
+                              RuntimeCallStop, CreateStopArguments(*s));
+                          builder_->CreateUnreachable();
+                        },
+                    },
+                    op.u);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::ConditionalGotoOp &cop) {
+                CheckInsertionPoint();
+                std::visit(
+                    common::visitors{
+                        [&](const parser::Statement<parser::IfThenStmt> *s) {
+                          const auto &exp{std::get<parser::ScalarLogicalExpr>(
+                              s->statement.t)
+                                              .thing.thing.value()};
+                          auto *cond{builder_->CreateExpr(ExprRef(exp))};
+                          AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
+                        },
+                        [&](const parser::Statement<parser::ElseIfStmt> *s) {
+                          const auto &exp{std::get<parser::ScalarLogicalExpr>(
+                              s->statement.t)
+                                              .thing.thing};
+                          auto *cond{builder_->CreateExpr(ExprRef(exp))};
+                          AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
+                        },
+                        [&](const parser::IfStmt *s) {
+                          const auto &exp{
+                              std::get<parser::ScalarLogicalExpr>(s->t)
+                                  .thing.thing};
+                          auto *cond{builder_->CreateExpr(ExprRef(exp))};
+                          AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
+                        },
+                        [&](const parser::Statement<parser::NonLabelDoStmt>
+                                *s) {
+                          AddOrQueueCGoto(
+                              BuildLoopLatchExpression(&s->statement),
+                              cop.trueLabel, cop.falseLabel);
+                        }},
+                    cop.u);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::SwitchIOOp &IOp) {
+                CheckInsertionPoint();
+                auto args{ComposeIOSwitchArgs(IOp)};
+                AddOrQueueSwitch<SwitchStmt>(
+                    args.exp, args.values, args.labels, CreateSwitchHelper);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::SwitchOp &sop) {
+                CheckInsertionPoint();
+                std::visit(
+                    common::visitors{
+                        [&](auto) {
+                          auto args{ComposeSwitchArgs(sop)};
+                          AddOrQueueSwitch<SwitchStmt>(args.exp, args.values,
+                              args.labels, CreateSwitchHelper);
+                        },
+                        [&](const parser::CaseConstruct *crct) {
+                          auto args{ComposeSwitchCaseArguments(crct, sop.refs)};
+                          AddOrQueueSwitch<SwitchCaseStmt>(args.exp,
+                              args.values, args.labels, CreateSwitchCaseHelper);
+                        },
+                        [&](const parser::SelectRankConstruct *crct) {
+                          auto args{ComposeSwitchRankArguments(crct, sop.refs)};
+                          AddOrQueueSwitch<SwitchRankStmt>(args.exp,
+                              args.values, args.labels, CreateSwitchRankHelper);
+                        },
+                        [&](const parser::SelectTypeConstruct *crct) {
+                          auto args{ComposeSwitchTypeArguments(crct, sop.refs)};
+                          AddOrQueueSwitch<SwitchTypeStmt>(args.exp,
+                              args.values, args.labels, CreateSwitchTypeHelper);
+                        },
+                    },
+                    sop.u);
+                builder_->ClearInsertionPoint();
+              },
+              [&](const flat::ActionOp &action) {
+                CheckInsertionPoint();
+                handleLinearAction(action, ad);
+              },
+              [&](const flat::DoIncrementOp &inc) {
+                CheckInsertionPoint();
+                handleLinearDoIncrement(inc);
+              },
+              [&](const flat::DoCompareOp &cmp) {
+                CheckInsertionPoint();
+                handleLinearDoCompare(cmp);
+              },
+              [&](const flat::BeginOp &con) {
+                std::visit(
+                    common::visitors{
+                        [&](const parser::AssociateConstruct *crct) {
+                          using A = parser::Statement<parser::AssociateStmt>;
+                          const auto &statement{std::get<A>(crct->t)};
+                          const auto &position{statement.source};
+                          EnterRegion(position);
+                          InitiateConstruct(&statement.statement);
+                        },
+                        [&](const parser::BlockConstruct *crct) {
+                          using A = parser::Statement<parser::BlockStmt>;
+                          EnterRegion(std::get<A>(crct->t).source);
+                        },
+                        [&](const parser::CaseConstruct *crct) {
+                          using A = parser::Statement<parser::SelectCaseStmt>;
+                          InitiateConstruct(&std::get<A>(crct->t).statement);
+                        },
+                        [&](const parser::ChangeTeamConstruct *crct) {
+                          using A = parser::Statement<parser::ChangeTeamStmt>;
+                          const auto &statement{std::get<A>(crct->t)};
+                          EnterRegion(statement.source);
+                          InitiateConstruct(&statement.statement);
+                        },
+                        [&](const parser::DoConstruct *crct) {
+                          using A = parser::Statement<parser::NonLabelDoStmt>;
+                          const auto &statement{std::get<A>(crct->t)};
+                          EnterRegion(statement.source);
+                          InitiateConstruct(&statement.statement);
+                        },
+                        [&](const parser::IfConstruct *crct) {
+                          using A = parser::Statement<parser::IfThenStmt>;
+                          InitiateConstruct(&std::get<A>(crct->t).statement);
+                        },
+                        [&](const parser::SelectRankConstruct *crct) {
+                          using A = parser::Statement<parser::SelectRankStmt>;
+                          const auto &statement{std::get<A>(crct->t)};
+                          EnterRegion(statement.source);
+                        },
+                        [&](const parser::SelectTypeConstruct *crct) {
+                          using A = parser::Statement<parser::SelectTypeStmt>;
+                          const auto &statement{std::get<A>(crct->t)};
+                          EnterRegion(statement.source);
+                        },
+                        [&](const parser::WhereConstruct *crct) {
+                          using A =
+                              parser::Statement<parser::WhereConstructStmt>;
+                          InitiateConstruct(&std::get<A>(crct->t).statement);
+                        },
+                        [&](const parser::ForallConstruct *crct) {
+                          using A =
+                              parser::Statement<parser::ForallConstructStmt>;
+                          InitiateConstruct(&std::get<A>(crct->t).statement);
+                        },
+                        [](const parser::CriticalConstruct *) { /*fixme*/ },
+                        [](const parser::CompilerDirective *) { /*fixme*/ },
+                        [](const parser::OpenMPConstruct *) { /*fixme*/ },
+                        [](const parser::OpenMPEndLoopDirective
+                                *) { /*fixme*/ },
+                    },
+                    con.u);
+                auto next{iter};
+                const auto &nextOp{*(++next)};
+                if (auto *op{std::get_if<flat::LabelOp>(&nextOp.u)}) {
+                  blockMap_.insert({op->get(), builder_->GetInsertionPoint()});
+                  ++iter;
+                }
+              },
+              [&](const flat::EndOp &con) {
+                std::visit(
+                    common::visitors{
+                        [](const auto &) {},
+                        [&](const parser::BlockConstruct *) { ExitRegion(); },
+                        [&](const parser::DoConstruct *crct) {
+                          const auto &statement{std::get<
+                              parser::Statement<parser::NonLabelDoStmt>>(
+                              crct->t)};
+                          FinishConstruct(&statement.statement);
+                          ExitRegion();
+                        },
+                        [&](const parser::AssociateConstruct *) {
+                          ExitRegion();
+                        },
+                        [&](const parser::ChangeTeamConstruct *) {
+                          ExitRegion();
+                        },
+                        [&](const parser::SelectTypeConstruct *) {
+                          ExitRegion();
+                        },
+                    },
+                    con.u);
+              },
+          },
+          op.u);
+    }
+  }
 
   void EnterRegion(const parser::CharBlock &pos) {
     auto *region{builder_->GetCurrentRegion()};
@@ -764,11 +1345,82 @@ public:
     }
   }
 
+  void AddOrQueueBranch(flat::LabelRef dest) {
+    auto iter{blockMap_.find(dest)};
+    if (iter != blockMap_.end()) {
+      builder_->CreateBranch(iter->second);
+    } else {
+      using namespace std::placeholders;
+      controlFlowEdgesToAdd_.emplace_back(std::bind(
+          [](FIRBuilder *builder, BasicBlock *block, flat::LabelRef dest,
+              const LabelMapType &map) {
+            builder->SetInsertionPoint(block);
+            CHECK(map.find(dest) != map.end() && "no destination");
+            builder->CreateBranch(map.find(dest)->second);
+          },
+          builder_, builder_->GetInsertionPoint(), dest, _1));
+    }
+  }
+
+  void AddOrQueueCGoto(Statement *condition, flat::LabelRef trueBlock,
+      flat::LabelRef falseBlock) {
+    auto trueIter{blockMap_.find(trueBlock)};
+    auto falseIter{blockMap_.find(falseBlock)};
+    if (trueIter != blockMap_.end() && falseIter != blockMap_.end()) {
+      builder_->CreateConditionalBranch(
+          condition, trueIter->second, falseIter->second);
+    } else {
+      using namespace std::placeholders;
+      controlFlowEdgesToAdd_.emplace_back(std::bind(
+          [](FIRBuilder *builder, BasicBlock *block, Statement *expr,
+              flat::LabelRef trueDest, flat::LabelRef falseDest,
+              const LabelMapType &map) {
+            builder->SetInsertionPoint(block);
+            CHECK(map.find(trueDest) != map.end());
+            CHECK(map.find(falseDest) != map.end());
+            builder->CreateConditionalBranch(
+                expr, map.find(trueDest)->second, map.find(falseDest)->second);
+          },
+          builder_, builder_->GetInsertionPoint(), condition, trueBlock,
+          falseBlock, _1));
+    }
+  }
+
   Variable *ConvertToVariable(const semantics::Symbol *symbol) {
     // FIXME: how to convert semantics::Symbol to evaluate::Variable?
     return new Variable(symbol);
   }
 
+  void AddOrQueueIGoto(AnalysisData &ad, const semantics::Symbol *symbol,
+      const std::vector<flat::LabelRef> &labels) {
+    auto useLabels{labels.empty() ? flat::GetAssign(ad, symbol) : labels};
+    auto defer{false};
+    IndirectBranchStmt::TargetListType blocks;
+    for (auto lab : useLabels) {
+      auto iter{blockMap_.find(lab)};
+      if (iter == blockMap_.end()) {
+        defer = true;
+        break;
+      } else {
+        blocks.push_back(iter->second);
+      }
+    }
+    if (defer) {
+      using namespace std::placeholders;
+      controlFlowEdgesToAdd_.emplace_back(std::bind(
+          [](FIRBuilder *builder, BasicBlock *block, Variable *variable,
+              const std::vector<flat::LabelRef> &fixme,
+              const LabelMapType &map) {
+            builder->SetInsertionPoint(block);
+            builder->CreateIndirectBr(variable, {});  // FIXME
+          },
+          builder_, builder_->GetInsertionPoint(), nullptr /*symbol*/,
+          useLabels, _1));
+    } else {
+      builder_->CreateIndirectBr(ConvertToVariable(symbol), blocks);
+    }
+  }
+
   void DrawRemainingArcs() {
     for (auto &arc : controlFlowEdgesToAdd_) {
       arc(blockMap_);
@@ -795,727 +1447,6 @@ public:
   bool debugLinearFIR_;
 };
 
-void FortranIRLowering::handleActionStatement(
-    AnalysisData &ad, const parser::Statement<parser::ActionStmt> &stmt) {
-  std::visit(
-      common::visitors{
-          [&](const common::Indirection<parser::AllocateStmt> &s) {
-            handleAllocateStmt(s.value());
-          },
-          [&](const common::Indirection<parser::AssignmentStmt> &s) {
-            handleAssignmentStmt(s.value());
-          },
-          [&](const common::Indirection<parser::BackspaceStmt> &s) {
-            builder_->CreateIOCall(InputOutputCallBackspace,
-                CreateBackspaceArguments(s.value().v));
-          },
-          [&](const common::Indirection<parser::CallStmt> &s) {
-            builder_->CreateCall(nullptr,
-                CreateCalleeValue(
-                    std::get<parser::ProcedureDesignator>(s.value().v.t)),
-                CreateCallArguments(
-                    std::get<std::list<parser::ActualArgSpec>>(s.value().v.t)));
-          },
-          [&](const common::Indirection<parser::CloseStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallClose, CreateCloseArguments(s.value().v));
-          },
-          [](const parser::ContinueStmt &) { WRONG_PATH(); },
-          [](const common::Indirection<parser::CycleStmt> &) { WRONG_PATH(); },
-          [&](const common::Indirection<parser::DeallocateStmt> &s) {
-            for (auto &alloc :
-                std::get<std::list<parser::AllocateObject>>(s.value().t)) {
-              builder_->CreateDealloc(
-                  CreateDeallocationValue(&alloc, &s.value()));
-            }
-          },
-          [&](const common::Indirection<parser::EndfileStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallEndfile, CreateEndfileArguments(s.value().v));
-          },
-          [&](const common::Indirection<parser::EventPostStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallEventPost, CreateEventPostArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::EventWaitStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallEventWait, CreateEventWaitArguments(s.value()));
-          },
-          [](const common::Indirection<parser::ExitStmt> &) { WRONG_PATH(); },
-          [&](const parser::FailImageStmt &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallFailImage, CreateFailImageArguments(s));
-          },
-          [&](const common::Indirection<parser::FlushStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallFlush, CreateFlushArguments(s.value().v));
-          },
-          [&](const common::Indirection<parser::FormTeamStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallFormTeam, CreateFormTeamArguments(s.value()));
-          },
-          [](const common::Indirection<parser::GotoStmt> &) { WRONG_PATH(); },
-          [](const common::Indirection<parser::IfStmt> &) { WRONG_PATH(); },
-          [&](const common::Indirection<parser::InquireStmt> &s) {
-            std::visit(
-                common::visitors{
-                    [&](const std::list<parser::InquireSpec> &specifiers) {
-                      builder_->CreateIOCall(InputOutputCallInquire,
-                          CreateInquireArguments(specifiers));
-                    },
-                    [&](const parser::InquireStmt::Iolength &iolength) {
-                      builder_->CreateIOCall(InputOutputCallInquire,
-                          CreateInquireArguments(iolength));
-                    },
-                },
-                s.value().u);
-          },
-          [&](const common::Indirection<parser::LockStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallLock, CreateLockArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::NullifyStmt> &s) {
-            for (auto &obj : s.value().v) {
-              std::visit(
-                  common::visitors{
-                      [&](const parser::Name &n) {
-                        auto s{builder_->CreateAddr(ToExpression(n))};
-                        builder_->CreateNullify(s);
-                      },
-                      [&](const parser::StructureComponent &sc) {
-                        auto s{builder_->CreateAddr(ToExpression(sc))};
-                        builder_->CreateNullify(s);
-                      },
-                  },
-                  obj.u);
-            }
-          },
-          [&](const common::Indirection<parser::OpenStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallOpen, CreateOpenArguments(s.value().v));
-          },
-          [&](const common::Indirection<parser::PointerAssignmentStmt> &s) {
-            auto *value{CreatePointerValue(s.value())};
-            auto addr{builder_->CreateAddr(
-                ExprRef(std::get<parser::Expr>(s.value().t)))};
-            builder_->CreateStore(addr, value);
-          },
-          [&](const common::Indirection<parser::PrintStmt> &s) {
-            builder_->CreateIOCall(InputOutputCallPrint,
-                CreatePrintArguments(std::get<parser::Format>(s.value().t),
-                    std::get<std::list<parser::OutputItem>>(s.value().t)));
-          },
-          [&](const common::Indirection<parser::ReadStmt> &s) {
-            builder_->CreateIOCall(InputOutputCallRead,
-                CreateReadArguments(s.value().iounit, s.value().format,
-                    s.value().controls, s.value().items));
-          },
-          [](const common::Indirection<parser::ReturnStmt> &) { WRONG_PATH(); },
-          [&](const common::Indirection<parser::RewindStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallRewind, CreateRewindArguments(s.value().v));
-          },
-          [&](const common::Indirection<parser::StopStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallStop, CreateStopArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::SyncAllStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallSyncAll, CreateSyncAllArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::SyncImagesStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallSyncImages, CreateSyncImagesArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::SyncMemoryStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallSyncMemory, CreateSyncMemoryArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::SyncTeamStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallSyncTeam, CreateSyncTeamArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::UnlockStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallUnlock, CreateUnlockArguments(s.value()));
-          },
-          [&](const common::Indirection<parser::WaitStmt> &s) {
-            builder_->CreateIOCall(
-                InputOutputCallWait, CreateWaitArguments(s.value().v));
-          },
-          [](const common::Indirection<parser::WhereStmt> &) { /*fixme*/ },
-          [&](const common::Indirection<parser::WriteStmt> &s) {
-            builder_->CreateIOCall(InputOutputCallWrite,
-                CreateWriteArguments(s.value().iounit, s.value().format,
-                    s.value().controls, s.value().items));
-          },
-          [](const common::Indirection<parser::ComputedGotoStmt> &) {
-            WRONG_PATH();
-          },
-          [](const common::Indirection<parser::ForallStmt> &) { /*fixme*/ },
-          [](const common::Indirection<parser::ArithmeticIfStmt> &) {
-            WRONG_PATH();
-          },
-          [&](const common::Indirection<parser::AssignStmt> &s) {
-            auto addr{builder_->CreateAddr(
-                ToExpression(std::get<parser::Name>(s.value().t)))};
-            auto *block{blockMap_
-                            .find(flat::FetchLabel(
-                                ad, std::get<parser::Label>(s.value().t))
-                                      .get())
-                            ->second};
-            builder_->CreateStore(addr, block);
-          },
-          [](const common::Indirection<parser::AssignedGotoStmt> &) {
-            WRONG_PATH();
-          },
-          [&](const common::Indirection<parser::PauseStmt> &s) {
-            builder_->CreateRuntimeCall(
-                RuntimeCallPause, CreatePauseArguments(s.value()));
-          },
-      },
-      stmt.statement.u);
-}
-
-template<typename SWITCHTYPE, typename F>
-void FortranIRLowering::AddOrQueueSwitch(Value condition,
-    const std::vector<typename SWITCHTYPE::ValueType> &values,
-    const std::vector<flat::LabelRef> &labels, F function) {
-  auto defer{false};
-  typename SWITCHTYPE::ValueSuccPairListType cases;
-  CHECK(values.size() == labels.size());
-  auto valiter{values.begin()};
-  for (auto lab : labels) {
-    auto labIter{blockMap_.find(lab)};
-    if (labIter == blockMap_.end()) {
-      defer = true;
-      break;
-    } else {
-      cases.emplace_back(*valiter++, labIter->second);
-    }
-  }
-  if (defer) {
-    using namespace std::placeholders;
-    controlFlowEdgesToAdd_.emplace_back(std::bind(
-        [](FIRBuilder *builder, BasicBlock *block, Value expr,
-            const std::vector<typename SWITCHTYPE::ValueType> &values,
-            const std::vector<flat::LabelRef> &labels, F function,
-            const LabelMapType &map) {
-          builder->SetInsertionPoint(block);
-          typename SWITCHTYPE::ValueSuccPairListType cases;
-          auto valiter{values.begin()};
-          for (auto &lab : labels) {
-            cases.emplace_back(*valiter++, map.find(lab)->second);
-          }
-          function(builder, expr, cases);
-        },
-        builder_, builder_->GetInsertionPoint(), condition, values, labels,
-        function, _1));
-  } else {
-    function(builder_, condition, cases);
-  }
-}
-
-void FortranIRLowering::AddOrQueueBranch(flat::LabelRef dest) {
-  auto iter{blockMap_.find(dest)};
-  if (iter != blockMap_.end()) {
-    builder_->CreateBranch(iter->second);
-  } else {
-    using namespace std::placeholders;
-    controlFlowEdgesToAdd_.emplace_back(std::bind(
-        [](FIRBuilder *builder, BasicBlock *block, flat::LabelRef dest,
-            const LabelMapType &map) {
-          builder->SetInsertionPoint(block);
-          CHECK(map.find(dest) != map.end() && "no destination");
-          builder->CreateBranch(map.find(dest)->second);
-        },
-        builder_, builder_->GetInsertionPoint(), dest, _1));
-  }
-}
-
-void FortranIRLowering::AddOrQueueCGoto(
-    Statement *condition, flat::LabelRef trueBlock, flat::LabelRef falseBlock) {
-  auto trueIter{blockMap_.find(trueBlock)};
-  auto falseIter{blockMap_.find(falseBlock)};
-  if (trueIter != blockMap_.end() && falseIter != blockMap_.end()) {
-    builder_->CreateConditionalBranch(
-        condition, trueIter->second, falseIter->second);
-  } else {
-    using namespace std::placeholders;
-    controlFlowEdgesToAdd_.emplace_back(std::bind(
-        [](FIRBuilder *builder, BasicBlock *block, Statement *expr,
-            flat::LabelRef trueDest, flat::LabelRef falseDest,
-            const LabelMapType &map) {
-          builder->SetInsertionPoint(block);
-          CHECK(map.find(trueDest) != map.end());
-          CHECK(map.find(falseDest) != map.end());
-          builder->CreateConditionalBranch(
-              expr, map.find(trueDest)->second, map.find(falseDest)->second);
-        },
-        builder_, builder_->GetInsertionPoint(), condition, trueBlock,
-        falseBlock, _1));
-  }
-}
-
-void FortranIRLowering::AddOrQueueIGoto(AnalysisData &ad,
-    const semantics::Symbol *symbol,
-    const std::vector<flat::LabelRef> &labels) {
-  auto useLabels{labels.empty() ? flat::GetAssign(ad, symbol) : labels};
-  auto defer{false};
-  IndirectBranchStmt::TargetListType blocks;
-  for (auto lab : useLabels) {
-    auto iter{blockMap_.find(lab)};
-    if (iter == blockMap_.end()) {
-      defer = true;
-      break;
-    } else {
-      blocks.push_back(iter->second);
-    }
-  }
-  if (defer) {
-    using namespace std::placeholders;
-    controlFlowEdgesToAdd_.emplace_back(std::bind(
-        [](FIRBuilder *builder, BasicBlock *block, Variable *variable,
-            const std::vector<flat::LabelRef> &fixme, const LabelMapType &map) {
-          builder->SetInsertionPoint(block);
-          builder->CreateIndirectBr(variable, {});  // FIXME
-        },
-        builder_, builder_->GetInsertionPoint(), nullptr /*symbol*/, useLabels,
-        _1));
-  } else {
-    builder_->CreateIndirectBr(ConvertToVariable(symbol), blocks);
-  }
-}
-
-void FortranIRLowering::InitiateConstruct(const parser::AssociateStmt *stmt) {
-  for (auto &assoc : std::get<std::list<parser::Association>>(stmt->t)) {
-    auto &selector{std::get<parser::Selector>(assoc.t)};
-    auto *expr{builder_->CreateExpr(std::visit(
-        common::visitors{
-            [&](const parser::Variable &v) { return ToExpression(v); },
-            [](const parser::Expr &e) { return *ExprRef(e); },
-        },
-        selector.u))};
-    auto name{
-        builder_->CreateAddr(ToExpression(std::get<parser::Name>(assoc.t)))};
-    builder_->CreateStore(name, expr);
-  }
-}
-
-void FortranIRLowering::InitiateConstruct(const parser::SelectCaseStmt *stmt) {
-  builder_->CreateExpr(
-      ExprRef(std::get<parser::Scalar<parser::Expr>>(stmt->t).thing));
-}
-
-void FortranIRLowering::InitiateConstruct(const parser::ChangeTeamStmt *stmt) {
-  // FIXME
-}
-
-void FortranIRLowering::InitiateConstruct(const parser::IfThenStmt *stmt) {
-  const auto &e{std::get<parser::ScalarLogicalExpr>(stmt->t).thing};
-  builder_->CreateExpr(ExprRef(e.thing));
-}
-
-void FortranIRLowering::InitiateConstruct(
-    const parser::WhereConstructStmt *stmt) {
-  const auto &e{std::get<parser::LogicalExpr>(stmt->t)};
-  builder_->CreateExpr(ExprRef(e.thing));
-}
-
-void FortranIRLowering::InitiateConstruct(
-    const parser::ForallConstructStmt *stmt) {
-  // FIXME
-}
-
-void FortranIRLowering::InitiateConstruct(const parser::NonLabelDoStmt *stmt) {
-  auto &ctrl{std::get<std::optional<parser::LoopControl>>(stmt->t)};
-  if (ctrl.has_value()) {
-    std::visit(
-        common::visitors{
-            [&](const parser::LoopBounds<parser::ScalarIntExpr> &bounds) {
-              auto name{
-                  builder_->CreateAddr(ToExpression(bounds.name.thing.thing))};
-              // evaluate e1, e2 [, e3] ...
-              auto *e1{builder_->CreateExpr(ExprRef(bounds.lower.thing.thing))};
-              auto *e2{builder_->CreateExpr(ExprRef(bounds.upper.thing.thing))};
-              Statement *e3;
-              if (bounds.step.has_value()) {
-                e3 = builder_->CreateExpr(ExprRef(bounds.step->thing.thing));
-              } else {
-                e3 = builder_->CreateExpr(CreateConstant(1));
-              }
-              // name <- e1
-              builder_->CreateStore(name, e1);
-              auto tripCounter{CreateTemp(GetDefaultIntegerType())};
-              // See 11.1.7.4.1, para. 1, item (3)
-              // totalTrips ::= iteration count = a
-              //   where a = (e2 - e1 + e3) / e3 if a > 0 and 0 otherwise
-              Expression tripExpr{ConsExpr<evaluate::Divide>(
-                  ConsExpr<evaluate::Add>(
-                      ConsExpr<evaluate::Subtract>(
-                          getApplyExpr(e2), getApplyExpr(e1)),
-                      getApplyExpr(e3)),
-                  getApplyExpr(e3))};
-              auto *totalTrips{builder_->CreateExpr(&tripExpr)};
-              builder_->CreateStore(tripCounter, totalTrips);
-              PushDoContext(stmt, name, tripCounter, e3);
-            },
-            [&](const parser::ScalarLogicalExpr &expr) {
-              // See 11.1.7.4.1, para. 2
-              // See BuildLoopLatchExpression()
-              PushDoContext(stmt);
-            },
-            [&](const parser::LoopControl::Concurrent &cc) {
-              // See 11.1.7.4.2
-              // FIXME
-            },
-        },
-        ctrl->u);
-  } else {
-    // loop forever (See 11.1.7.4.1, para. 2)
-    PushDoContext(stmt);
-  }
-}
-
-// Image related runtime argument translations ...
-RuntimeCallArguments FortranIRLowering::CreateEventPostArguments(
-    const parser::EventPostStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateEventWaitArguments(
-    const parser::EventWaitStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateFailImageArguments(
-    const parser::FailImageStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateFormTeamArguments(
-    const parser::FormTeamStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateLockArguments(
-    const parser::LockStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreatePauseArguments(
-    const parser::PauseStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateStopArguments(
-    const parser::StopStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateSyncAllArguments(
-    const parser::SyncAllStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateSyncImagesArguments(
-    const parser::SyncImagesStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateSyncMemoryArguments(
-    const parser::SyncMemoryStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateSyncTeamArguments(
-    const parser::SyncTeamStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-RuntimeCallArguments FortranIRLowering::CreateUnlockArguments(
-    const parser::UnlockStmt &stmt) {
-  return RuntimeCallArguments{};
-}
-
-// I/O related runtime argument translations ...
-IOCallArguments FortranIRLowering::CreateBackspaceArguments(
-    const std::list<parser::PositionOrFlushSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateCloseArguments(
-    const std::list<parser::CloseStmt::CloseSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateEndfileArguments(
-    const std::list<parser::PositionOrFlushSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateFlushArguments(
-    const std::list<parser::PositionOrFlushSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateRewindArguments(
-    const std::list<parser::PositionOrFlushSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateInquireArguments(
-    const std::list<parser::InquireSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateInquireArguments(
-    const parser::InquireStmt::Iolength &iolength) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateOpenArguments(
-    const std::list<parser::ConnectSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateWaitArguments(
-    const std::list<parser::WaitSpec> &specifiers) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreatePrintArguments(
-    const parser::Format &format,
-    const std::list<parser::OutputItem> &outputs) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateReadArguments(
-    const std::optional<parser::IoUnit> &ioUnit,
-    const std::optional<parser::Format> &format,
-    const std::list<parser::IoControlSpec> &controls,
-    const std::list<parser::InputItem> &inputs) {
-  return IOCallArguments{};
-}
-IOCallArguments FortranIRLowering::CreateWriteArguments(
-    const std::optional<parser::IoUnit> &ioUnit,
-    const std::optional<parser::Format> &format,
-    const std::list<parser::IoControlSpec> &controls,
-    const std::list<parser::OutputItem> &outputs) {
-  return IOCallArguments{};
-}
-
-void FortranIRLowering::ConstructFIR(AnalysisData &ad) {
-  for (auto iter{linearOperations_.begin()}, iend{linearOperations_.end()};
-       iter != iend; ++iter) {
-    const auto &op{*iter};
-    std::visit(
-        common::visitors{
-            [&](const flat::LabelOp &op) {
-              auto *newBlock{CreateBlock(builder_->GetCurrentRegion())};
-              blockMap_.insert({op.get(), newBlock});
-              if (builder_->GetInsertionPoint()) {
-                builder_->CreateBranch(newBlock);
-              }
-              builder_->SetInsertionPoint(newBlock);
-            },
-            [&](const flat::GotoOp &op) {
-              CheckInsertionPoint();
-              AddOrQueueBranch(op.target);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::IndirectGotoOp &op) {
-              CheckInsertionPoint();
-              AddOrQueueIGoto(ad, op.symbol, op.labelRefs);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::ReturnOp &op) {
-              CheckInsertionPoint();
-              std::visit(
-                  common::visitors{
-                      [&](const parser::FailImageStmt *s) {
-                        builder_->CreateRuntimeCall(
-                            RuntimeCallFailImage, CreateFailImageArguments(*s));
-                        builder_->CreateUnreachable();
-                      },
-                      [&](const parser::ReturnStmt *s) {
-                        // alt-return
-                        if (s->v) {
-                          auto *exp{ExprRef(s->v->thing.thing)};
-                          auto app{builder_->QualifiedCreateExpr(exp)};
-                          builder_->CreateReturn(app);
-                        } else {
-                          auto zero{
-                              builder_->QualifiedCreateExpr(CreateConstant(0))};
-                          builder_->CreateReturn(zero);
-                        }
-                      },
-                      [&](const parser::StopStmt *s) {
-                        builder_->CreateRuntimeCall(
-                            RuntimeCallStop, CreateStopArguments(*s));
-                        builder_->CreateUnreachable();
-                      },
-                  },
-                  op.u);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::ConditionalGotoOp &cop) {
-              CheckInsertionPoint();
-              std::visit(
-                  common::visitors{
-                      [&](const parser::Statement<parser::IfThenStmt> *s) {
-                        const auto &exp{
-                            std::get<parser::ScalarLogicalExpr>(s->statement.t)
-                                .thing.thing.value()};
-                        SEMANTICS_CHECK(ExprRef(exp),
-                            "IF THEN condition expression missing");
-                        auto *cond{builder_->CreateExpr(ExprRef(exp))};
-                        AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
-                      },
-                      [&](const parser::Statement<parser::ElseIfStmt> *s) {
-                        const auto &exp{
-                            std::get<parser::ScalarLogicalExpr>(s->statement.t)
-                                .thing.thing.value()};
-                        SEMANTICS_CHECK(ExprRef(exp),
-                            "ELSE IF condition expression missing");
-                        auto *cond{builder_->CreateExpr(ExprRef(exp))};
-                        AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
-                      },
-                      [&](const parser::IfStmt *s) {
-                        const auto &exp{
-                            std::get<parser::ScalarLogicalExpr>(s->t)
-                                .thing.thing.value()};
-                        SEMANTICS_CHECK(
-                            ExprRef(exp), "IF condition expression missing");
-                        auto *cond{builder_->CreateExpr(ExprRef(exp))};
-                        AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
-                      },
-                      [&](const parser::Statement<parser::NonLabelDoStmt> *s) {
-                        AddOrQueueCGoto(BuildLoopLatchExpression(&s->statement),
-                            cop.trueLabel, cop.falseLabel);
-                      }},
-                  cop.u);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::SwitchIOOp &IOp) {
-              CheckInsertionPoint();
-              auto args{ComposeIOSwitchArgs(IOp)};
-              AddOrQueueSwitch<SwitchStmt>(
-                  args.exp, args.values, args.labels, CreateSwitchHelper);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::SwitchOp &sop) {
-              CheckInsertionPoint();
-              std::visit(
-                  common::visitors{
-                      [&](auto) {
-                        auto args{ComposeSwitchArgs(sop)};
-                        AddOrQueueSwitch<SwitchStmt>(args.exp, args.values,
-                            args.labels, CreateSwitchHelper);
-                      },
-                      [&](const parser::CaseConstruct *crct) {
-                        auto args{ComposeSwitchCaseArguments(crct, sop.refs)};
-                        AddOrQueueSwitch<SwitchCaseStmt>(args.exp, args.values,
-                            args.labels, CreateSwitchCaseHelper);
-                      },
-                      [&](const parser::SelectRankConstruct *crct) {
-                        auto args{ComposeSwitchRankArguments(crct, sop.refs)};
-                        AddOrQueueSwitch<SwitchRankStmt>(args.exp, args.values,
-                            args.labels, CreateSwitchRankHelper);
-                      },
-                      [&](const parser::SelectTypeConstruct *crct) {
-                        auto args{ComposeSwitchTypeArguments(crct, sop.refs)};
-                        AddOrQueueSwitch<SwitchTypeStmt>(args.exp, args.values,
-                            args.labels, CreateSwitchTypeHelper);
-                      },
-                  },
-                  sop.u);
-              builder_->ClearInsertionPoint();
-            },
-            [&](const flat::ActionOp &action) {
-              CheckInsertionPoint();
-              handleLinearAction(action, ad);
-            },
-            [&](const flat::DoIncrementOp &inc) {
-              CheckInsertionPoint();
-              handleLinearDoIncrement(inc);
-            },
-            [&](const flat::DoCompareOp &cmp) {
-              CheckInsertionPoint();
-              handleLinearDoCompare(cmp);
-            },
-            [&](const flat::BeginOp &con) {
-              std::visit(
-                  common::visitors{
-                      [&](const parser::AssociateConstruct *crct) {
-                        using A = parser::Statement<parser::AssociateStmt>;
-                        const auto &statement{std::get<A>(crct->t)};
-                        const auto &position{statement.source};
-                        EnterRegion(position);
-                        InitiateConstruct(&statement.statement);
-                      },
-                      [&](const parser::BlockConstruct *crct) {
-                        using A = parser::Statement<parser::BlockStmt>;
-                        EnterRegion(std::get<A>(crct->t).source);
-                      },
-                      [&](const parser::CaseConstruct *crct) {
-                        using A = parser::Statement<parser::SelectCaseStmt>;
-                        InitiateConstruct(&std::get<A>(crct->t).statement);
-                      },
-                      [&](const parser::ChangeTeamConstruct *crct) {
-                        using A = parser::Statement<parser::ChangeTeamStmt>;
-                        const auto &statement{std::get<A>(crct->t)};
-                        EnterRegion(statement.source);
-                        InitiateConstruct(&statement.statement);
-                      },
-                      [&](const parser::DoConstruct *crct) {
-                        using A = parser::Statement<parser::NonLabelDoStmt>;
-                        const auto &statement{std::get<A>(crct->t)};
-                        EnterRegion(statement.source);
-                        InitiateConstruct(&statement.statement);
-                      },
-                      [&](const parser::IfConstruct *crct) {
-                        using A = parser::Statement<parser::IfThenStmt>;
-                        InitiateConstruct(&std::get<A>(crct->t).statement);
-                      },
-                      [&](const parser::SelectRankConstruct *crct) {
-                        using A = parser::Statement<parser::SelectRankStmt>;
-                        const auto &statement{std::get<A>(crct->t)};
-                        EnterRegion(statement.source);
-                      },
-                      [&](const parser::SelectTypeConstruct *crct) {
-                        using A = parser::Statement<parser::SelectTypeStmt>;
-                        const auto &statement{std::get<A>(crct->t)};
-                        EnterRegion(statement.source);
-                      },
-                      [&](const parser::WhereConstruct *crct) {
-                        using A = parser::Statement<parser::WhereConstructStmt>;
-                        InitiateConstruct(&std::get<A>(crct->t).statement);
-                      },
-                      [&](const parser::ForallConstruct *crct) {
-                        using A =
-                            parser::Statement<parser::ForallConstructStmt>;
-                        InitiateConstruct(&std::get<A>(crct->t).statement);
-                      },
-                      [](const parser::CriticalConstruct *) { /*fixme*/ },
-                      [](const parser::CompilerDirective *) { /*fixme*/ },
-                      [](const parser::OpenMPConstruct *) { /*fixme*/ },
-                      [](const parser::OpenMPEndLoopDirective *) { /*fixme*/ },
-                  },
-                  con.u);
-              auto next{iter};
-              const auto &nextOp{*(++next)};
-              if (auto *op{std::get_if<flat::LabelOp>(&nextOp.u)}) {
-                blockMap_.insert({op->get(), builder_->GetInsertionPoint()});
-                ++iter;
-              }
-            },
-            [&](const flat::EndOp &con) {
-              std::visit(
-                  common::visitors{
-                      [](const auto &) {},
-                      [&](const parser::BlockConstruct *) { ExitRegion(); },
-                      [&](const parser::DoConstruct *crct) {
-                        const auto &statement{
-                            std::get<parser::Statement<parser::NonLabelDoStmt>>(
-                                crct->t)};
-                        FinishConstruct(&statement.statement);
-                        ExitRegion();
-                      },
-                      [&](const parser::AssociateConstruct *) { ExitRegion(); },
-                      [&](const parser::ChangeTeamConstruct *) {
-                        ExitRegion();
-                      },
-                      [&](const parser::SelectTypeConstruct *) {
-                        ExitRegion();
-                      },
-                  },
-                  con.u);
-            },
-        },
-        op.u);
-  }
-}
-
 Program *CreateFortranIR(const parser::Program &program,
     semantics::SemanticsContext &semanticsContext, bool debugLinearIR) {
   FortranIRLowering converter{semanticsContext, debugLinearIR};
index d88502e..5ff4f36 100644 (file)
@@ -56,7 +56,7 @@ struct FIRBuilder {
   BasicBlock *GetInsertionPoint() const { return cursorBlock_; }
 
   // create the various statements
-  QualifiedStmt<Addressable_impl> CreateAddr(const Expression *e) {
+  QualifiedStmt<Addressable_impl> CreateAddr(const Expression &e) {
     return QualifiedInsert<Addressable_impl>(LocateExprStmt::Create(e));
   }
   QualifiedStmt<Addressable_impl> CreateAddr(Expression &&e) {
@@ -80,16 +80,16 @@ struct FIRBuilder {
   Statement *CreateDealloc(QualifiedStmt<AllocateInsn> alloc) {
     return Insert(DeallocateInsn::Create(alloc));
   }
-  Statement *CreateExpr(const Expression *e) {
+  Statement *CreateExpr(const Expression &e) {
     return Insert(ApplyExprStmt::Create(e));
   }
   Statement *CreateExpr(Expression &&e) {
     return Insert(ApplyExprStmt::Create(std::move(e)));
   }
-  ApplyExprStmt *MakeAsExpr(const Expression *e) {
+  ApplyExprStmt *MakeAsExpr(const Expression &e) {
     return GetApplyExpr(CreateExpr(e));
   }
-  QualifiedStmt<ApplyExprStmt> QualifiedCreateExpr(const Expression *e) {
+  QualifiedStmt<ApplyExprStmt> QualifiedCreateExpr(const Expression &e) {
     return QualifiedInsert<ApplyExprStmt>(ApplyExprStmt::Create(e));
   }
   QualifiedStmt<ApplyExprStmt> QualifiedCreateExpr(Expression &&e) {
index e0a1133..57c65f3 100644 (file)
@@ -230,7 +230,7 @@ public:
   struct Default {};  // RANK DEFAULT
   struct AssumedSize {};  // RANK(*)
   struct Exactly {  // RANK(n)
-    Expression *v;
+    const Expression *v;
   };
   using ValueType = std::variant<Exactly, AssumedSize, Default>;
   using ValueSuccPairType = std::pair<ValueType, BasicBlock *>;
@@ -295,7 +295,7 @@ protected:
 // Compute the value of an expression
 class ApplyExprStmt : public ActionStmt_impl {
 public:
-  static ApplyExprStmt Create(const Expression *e) { return ApplyExprStmt{*e}; }
+  static ApplyExprStmt Create(const Expression &e) { return ApplyExprStmt{e}; }
   static ApplyExprStmt Create(Expression &&e) {
     return ApplyExprStmt{std::move(e)};
   }
@@ -323,8 +323,8 @@ protected:
 // Compute the location of an expression
 class LocateExprStmt : public Addressable_impl {
 public:
-  static LocateExprStmt Create(const Expression *e) {
-    return LocateExprStmt(*e);
+  static LocateExprStmt Create(const Expression &e) {
+    return LocateExprStmt(e);
   }
   static LocateExprStmt Create(Expression &&e) { return LocateExprStmt(e); }
 
diff --git a/flang/lib/bridge/CMakeLists.txt b/flang/lib/bridge/CMakeLists.txt
deleted file mode 100644 (file)
index bdccc92..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2018-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.
-
-add_library(FortranBridge
-  ir-gen.cc
-)
-
-target_link_libraries(FortranBridge
-  FortranCommon
-  FortranFIR
-)
-
diff --git a/flang/lib/bridge/ir-gen.cc b/flang/lib/bridge/ir-gen.cc
deleted file mode 100644 (file)
index e264a64..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 "ir-gen.h"
-
-namespace Fortran::bridge {
-
-void GenerateIR(void) {
-}
-
-}
diff --git a/flang/lib/bridge/ir-gen.h b/flang/lib/bridge/ir-gen.h
deleted file mode 100644 (file)
index 6505d16..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-namespace Fortran::bridge {
-
-/// Generate LLVM-IR
-void GenerateIR(void);
-
-}