2169307cd8
Original-commit: flang-compiler/f18@4dd4766f4d Reviewed-on: https://github.com/flang-compiler/f18/pull/295
139 lines
4.9 KiB
C++
139 lines
4.9 KiB
C++
// Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef FORTRAN_FIR_BUILDER_H_
|
|
#define FORTRAN_FIR_BUILDER_H_
|
|
|
|
#include "stmt.h"
|
|
#include <initializer_list>
|
|
|
|
namespace Fortran::FIR {
|
|
|
|
struct FIRBuilder {
|
|
explicit FIRBuilder(BasicBlock &block)
|
|
: cursorRegion_{block.getParent()}, cursorBlock_{&block} {}
|
|
template<typename A> Statement &Insert(A &&s) {
|
|
CHECK(GetInsertionPoint());
|
|
auto *statement{new Statement(GetInsertionPoint(), s)};
|
|
return *statement;
|
|
}
|
|
template<typename A> Statement &InsertTerminator(A &&s) {
|
|
auto &statement{Insert(s)};
|
|
for (auto *block : s.succ_blocks()) {
|
|
block->addPred(GetInsertionPoint());
|
|
}
|
|
return statement;
|
|
}
|
|
void SetInsertionPoint(BasicBlock *bb) {
|
|
cursorBlock_ = bb;
|
|
cursorRegion_ = bb->getParent();
|
|
}
|
|
void ClearInsertionPoint() { cursorBlock_ = nullptr; }
|
|
BasicBlock *GetInsertionPoint() const { return cursorBlock_; }
|
|
|
|
Statement &CreateAlloc(const Expression *object) {
|
|
return Insert(AllocateStmt::Create(object));
|
|
}
|
|
Statement &CreateAssign(const PathVariable *lhs, const Expression *rhs) {
|
|
return Insert(AssignmentStmt::Create(lhs, rhs));
|
|
}
|
|
Statement &CreateAssign(const semantics::Symbol *lhs, BasicBlock *rhs) {
|
|
return Insert(LabelAssignStmt::Create(lhs, rhs));
|
|
}
|
|
Statement &CreateBranch(BasicBlock *block) {
|
|
return InsertTerminator(BranchStmt::Create(block));
|
|
}
|
|
Statement &CreateCall(const FunctionType *type, const Value *callee,
|
|
CallArguments &&arguments) {
|
|
return Insert(CallStmt::Create(type, callee, std::move(arguments)));
|
|
}
|
|
template<typename A>
|
|
Statement &CreateConditionalBranch(
|
|
A *condition, BasicBlock *trueBlock, BasicBlock *falseBlock) {
|
|
return InsertTerminator(
|
|
BranchStmt::Create(condition, trueBlock, falseBlock));
|
|
}
|
|
Statement &CreateDealloc(const Expression *object) {
|
|
return Insert(DeallocateStmt::Create(object));
|
|
}
|
|
template<typename A> Statement &CreateExpr(const A *a) {
|
|
return Insert(ExprStmt::Create(a));
|
|
}
|
|
Statement &CreateIOCall(
|
|
InputOutputCallType call, IOCallArguments &&arguments) {
|
|
return Insert(IORuntimeStmt::Create(call, std::move(arguments)));
|
|
}
|
|
Statement &CreateIndirectBr(
|
|
Variable *var, const std::vector<BasicBlock *> &potentials) {
|
|
return InsertTerminator(IndirectBrStmt::Create(var, potentials));
|
|
}
|
|
Statement &CreateNullify(const parser::NullifyStmt *statement) {
|
|
return Insert(DisassociateStmt::Create(statement));
|
|
}
|
|
Statement &CreatePointerAssign(const Expression *lhs, const Expression *rhs) {
|
|
return Insert(PointerAssignStmt::Create(lhs, rhs));
|
|
}
|
|
Statement &CreateRetVoid() { return InsertTerminator(ReturnStmt::Create()); }
|
|
template<typename A> Statement &CreateReturn(A *expr) {
|
|
return InsertTerminator(ReturnStmt::Create(expr));
|
|
}
|
|
Statement &CreateRuntimeCall(
|
|
RuntimeCallType call, RuntimeCallArguments &&arguments) {
|
|
return Insert(RuntimeStmt::Create(call, std::move(arguments)));
|
|
}
|
|
Statement &CreateSwitch(const Evaluation &condition, BasicBlock *defaultCase,
|
|
const SwitchStmt::ValueSuccPairListType &rest) {
|
|
return InsertTerminator(SwitchStmt::Create(condition, defaultCase, rest));
|
|
}
|
|
Statement &CreateSwitchCase(const Evaluation &condition,
|
|
BasicBlock *defaultCase,
|
|
const SwitchCaseStmt::ValueSuccPairListType &rest) {
|
|
return InsertTerminator(
|
|
SwitchCaseStmt::Create(condition, defaultCase, rest));
|
|
}
|
|
Statement &CreateSwitchType(const Evaluation &condition,
|
|
BasicBlock *defaultCase,
|
|
const SwitchTypeStmt::ValueSuccPairListType &rest) {
|
|
return InsertTerminator(
|
|
SwitchTypeStmt::Create(condition, defaultCase, rest));
|
|
}
|
|
Statement &CreateSwitchRank(const Evaluation &condition,
|
|
BasicBlock *defaultCase,
|
|
const SwitchRankStmt::ValueSuccPairListType &rest) {
|
|
return InsertTerminator(
|
|
SwitchRankStmt::Create(condition, defaultCase, rest));
|
|
}
|
|
Statement &CreateUnreachable() {
|
|
return InsertTerminator(UnreachableStmt::Create());
|
|
}
|
|
|
|
void PushBlock(BasicBlock *block) { blockStack_.push_back(block); }
|
|
BasicBlock *PopBlock() {
|
|
auto *block{blockStack_.back()};
|
|
blockStack_.pop_back();
|
|
return block;
|
|
}
|
|
void dump() const;
|
|
void SetCurrentRegion(Region *region) { cursorRegion_ = region; }
|
|
Region *GetCurrentRegion() const { return cursorRegion_; }
|
|
|
|
private:
|
|
Region *cursorRegion_;
|
|
BasicBlock *cursorBlock_;
|
|
std::vector<BasicBlock *> blockStack_;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|