From: Eric Schweitz Date: Wed, 20 Mar 2019 20:01:26 +0000 (-0700) Subject: [flang] improved output on flat fir X-Git-Tag: llvmorg-12-init~9537^2~1527 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84264dc79bddcb7ffa7ca423e2e218fed5c00d4d;p=platform%2Fupstream%2Fllvm.git [flang] improved output on flat fir Original-commit: flang-compiler/f18@9be07963a5f70b71f4e9c38f7d89c837dbedc1a1 Reviewed-on: https://github.com/flang-compiler/f18/pull/354 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/FIR/afforestation.cc b/flang/lib/FIR/afforestation.cc index 8ba25cf..6745f69 100644 --- a/flang/lib/FIR/afforestation.cc +++ b/flang/lib/FIR/afforestation.cc @@ -987,25 +987,25 @@ public: const auto &op{*iter}; std::visit( common::visitors{ - [&](const flat::LabelOp &linearLabel) { + [&](const flat::LabelOp &op) { auto *newBlock{CreateBlock(builder_->GetCurrentRegion())}; - blockMap_.insert({linearLabel.get(), newBlock}); + blockMap_.insert({op.get(), newBlock}); if (builder_->GetInsertionPoint()) { builder_->CreateBranch(newBlock); } builder_->SetInsertionPoint(newBlock); }, - [&](const flat::GotoOp &linearGoto) { + [&](const flat::GotoOp &op) { CheckInsertionPoint(); - AddOrQueueBranch(linearGoto.target); + AddOrQueueBranch(op.target); builder_->ClearInsertionPoint(); }, - [&](const flat::IndirectGotoOp &linearIGoto) { + [&](const flat::IndirectGotoOp &op) { CheckInsertionPoint(); - AddOrQueueIGoto(ad, linearIGoto.symbol, linearIGoto.labelRefs); + AddOrQueueIGoto(ad, op.symbol, op.labelRefs); builder_->ClearInsertionPoint(); }, - [&](const flat::ReturnOp &linearReturn) { + [&](const flat::ReturnOp &op) { CheckInsertionPoint(); std::visit( common::visitors{ @@ -1031,10 +1031,10 @@ public: builder_->CreateUnreachable(); }, }, - linearReturn.u); + op.u); builder_->ClearInsertionPoint(); }, - [&](const flat::ConditionalGotoOp &linearConditionalGoto) { + [&](const flat::ConditionalGotoOp &cop) { CheckInsertionPoint(); std::visit( common::visitors{ @@ -1045,8 +1045,7 @@ public: SEMANTICS_CHECK(ExprRef(exp), "IF THEN condition expression missing"); auto *cond{builder_->CreateExpr(ExprRef(exp))}; - AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel, - linearConditionalGoto.falseLabel); + AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel); }, [&](const parser::Statement *s) { const auto &exp{std::get( @@ -1055,8 +1054,7 @@ public: SEMANTICS_CHECK(ExprRef(exp), "ELSE IF condition expression missing"); auto *cond{builder_->CreateExpr(ExprRef(exp))}; - AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel, - linearConditionalGoto.falseLabel); + AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel); }, [&](const parser::IfStmt *s) { const auto &exp{ @@ -1065,37 +1063,35 @@ public: SEMANTICS_CHECK( ExprRef(exp), "IF condition expression missing"); auto *cond{builder_->CreateExpr(ExprRef(exp))}; - AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel, - linearConditionalGoto.falseLabel); + AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel); }, [&](const parser::Statement *s) { AddOrQueueCGoto( BuildLoopLatchExpression(&s->statement), - linearConditionalGoto.trueLabel, - linearConditionalGoto.falseLabel); + cop.trueLabel, cop.falseLabel); }}, - linearConditionalGoto.u); + cop.u); builder_->ClearInsertionPoint(); }, - [&](const flat::SwitchIOOp &linearIO) { + [&](const flat::SwitchIOOp &IOp) { CheckInsertionPoint(); AddOrQueueSwitch( - NOTHING, linearIO.next, {}, {}, CreateSwitchHelper); + NOTHING, IOp.next, {}, {}, CreateSwitchHelper); builder_->ClearInsertionPoint(); }, - [&](const flat::SwitchOp &linearSwitch) { + [&](const flat::SwitchOp &sop) { CheckInsertionPoint(); std::visit( common::visitors{ [&](auto) { - auto args{ComposeSwitchArgs(linearSwitch)}; + auto args{ComposeSwitchArgs(sop)}; AddOrQueueSwitch(args.exp, args.defLab, args.values, args.labels, CreateSwitchHelper); }, [&](const parser::CaseConstruct *caseConstruct) { auto args{ComposeSwitchCaseArguments( - caseConstruct, linearSwitch.refs)}; + caseConstruct, sop.refs)}; AddOrQueueSwitch(args.exp, args.defLab, args.values, args.labels, CreateSwitchCaseHelper); @@ -1103,7 +1099,7 @@ public: [&](const parser::SelectRankConstruct *selectRankConstruct) { auto args{ComposeSwitchRankArguments( - selectRankConstruct, linearSwitch.refs)}; + selectRankConstruct, sop.refs)}; AddOrQueueSwitch(args.exp, args.defLab, args.values, args.labels, CreateSwitchRankHelper); @@ -1111,13 +1107,13 @@ public: [&](const parser::SelectTypeConstruct *selectTypeConstruct) { auto args{ComposeSwitchTypeArguments( - selectTypeConstruct, linearSwitch.refs)}; + selectTypeConstruct, sop.refs)}; AddOrQueueSwitch(args.exp, args.defLab, args.values, args.labels, CreateSwitchTypeHelper); }, }, - linearSwitch.u); + sop.u); builder_->ClearInsertionPoint(); }, [&](const flat::ActionOp &action) { @@ -1132,72 +1128,72 @@ public: CheckInsertionPoint(); handleLinearDoCompare(cmp); }, - [&](const flat::BeginOp &linearConstruct) { + [&](const flat::BeginOp &con) { std::visit( common::visitors{ - [&](const parser::AssociateConstruct *construct) { + [&](const parser::AssociateConstruct *crct) { const auto &statement{std::get< parser::Statement>( - construct->t)}; + crct->t)}; const auto &position{statement.source}; EnterRegion(position); InitiateConstruct(&statement.statement); }, - [&](const parser::BlockConstruct *construct) { + [&](const parser::BlockConstruct *crct) { EnterRegion( std::get>( - construct->t) + crct->t) .source); }, - [&](const parser::CaseConstruct *construct) { + [&](const parser::CaseConstruct *crct) { InitiateConstruct( &std::get< parser::Statement>( - construct->t) + crct->t) .statement); }, - [&](const parser::ChangeTeamConstruct *construct) { + [&](const parser::ChangeTeamConstruct *crct) { const auto &statement{std::get< parser::Statement>( - construct->t)}; + crct->t)}; EnterRegion(statement.source); InitiateConstruct(&statement.statement); }, - [&](const parser::DoConstruct *construct) { + [&](const parser::DoConstruct *crct) { const auto &statement{std::get< parser::Statement>( - construct->t)}; + crct->t)}; EnterRegion(statement.source); InitiateConstruct(&statement.statement); }, - [&](const parser::IfConstruct *construct) { + [&](const parser::IfConstruct *crct) { InitiateConstruct( &std::get>( - construct->t) + crct->t) .statement); }, - [&](const parser::SelectRankConstruct *construct) { + [&](const parser::SelectRankConstruct *crct) { const auto &statement{std::get< parser::Statement>( - construct->t)}; + crct->t)}; EnterRegion(statement.source); }, - [&](const parser::SelectTypeConstruct *construct) { + [&](const parser::SelectTypeConstruct *crct) { const auto &statement{std::get< parser::Statement>( - construct->t)}; + crct->t)}; EnterRegion(statement.source); }, - [&](const parser::WhereConstruct *construct) { + [&](const parser::WhereConstruct *crct) { InitiateConstruct( &std::get>(construct->t) + parser::WhereConstructStmt>>(crct->t) .statement); }, - [&](const parser::ForallConstruct *construct) { + [&](const parser::ForallConstruct *crct) { InitiateConstruct( &std::get>(construct->t) + parser::ForallConstructStmt>>(crct->t) .statement); }, [](const parser::CriticalConstruct *) { /*fixme*/ }, @@ -1206,21 +1202,21 @@ public: [](const parser::OpenMPEndLoopDirective *) { /*fixme*/ }, }, - linearConstruct.u); + con.u); auto next{iter}; const auto &nextOp{*(++next)}; std::visit( common::visitors{ [](const auto &) {}, - [&](const flat::LabelOp &linearLabel) { - blockMap_.insert({linearLabel.get(), - builder_->GetInsertionPoint()}); + [&](const flat::LabelOp &op) { + blockMap_.insert( + {op.get(), builder_->GetInsertionPoint()}); ++iter; }, }, nextOp.u); }, - [&](const flat::EndOp &linearConstruct) { + [&](const flat::EndOp &con) { std::visit( common::visitors{ [](const auto &) {}, @@ -1242,12 +1238,13 @@ public: ExitRegion(); }, }, - linearConstruct.u); + con.u); }, }, op.u); } } + void EnterRegion(const parser::CharBlock &pos) { auto *region{builder_->GetCurrentRegion()}; auto *scope{semanticsContext_.globalScope().FindScope(pos)}; @@ -1257,14 +1254,17 @@ public: builder_->CreateBranch(block); builder_->SetInsertionPoint(block); } + void ExitRegion() { builder_->SetCurrentRegion(builder_->GetCurrentRegion()->GetEnclosing()); } + void CheckInsertionPoint() { if (!builder_->GetInsertionPoint()) { builder_->SetInsertionPoint(CreateBlock(builder_->GetCurrentRegion())); } } + void AddOrQueueBranch(flat::LabelRef dest) { auto iter{blockMap_.find(dest)}; if (iter != blockMap_.end()) { @@ -1281,6 +1281,7 @@ public: builder_, builder_->GetInsertionPoint(), dest, _1)); } } + void AddOrQueueCGoto(Statement *condition, flat::LabelRef trueBlock, flat::LabelRef falseBlock) { auto trueIter{blockMap_.find(trueBlock)}; diff --git a/flang/lib/FIR/flattened.cc b/flang/lib/FIR/flattened.cc index c509726..49ca311 100644 --- a/flang/lib/FIR/flattened.cc +++ b/flang/lib/FIR/flattened.cc @@ -52,7 +52,7 @@ void LabelOp::setReferenced() const { builder_.setReferenced(label_); } bool LabelOp::isReferenced() const { return builder_.isReferenced(label_); } -void AddAssign(AnalysisData &ad, const semantics::Symbol *symbol, +static void AddAssign(AnalysisData &ad, const semantics::Symbol *symbol, const parser::Label &label) { ad.assignMap[symbol].insert(label); } @@ -66,7 +66,7 @@ std::vector GetAssign( return result; } -std::tuple FindStack( +static std::tuple FindStack( const std::vector> &stack, const parser::Name *key) { @@ -90,31 +90,33 @@ LabelOp FetchLabel(AnalysisData &ad, const parser::Label &label) { return iter->second; } -LabelOp BuildNewLabel(AnalysisData &ad) { return LabelOp{ad.labelBuilder}; } +static LabelOp BuildNewLabel(AnalysisData &ad) { + return LabelOp{ad.labelBuilder}; +} -template parser::Label GetErr(const T &stmt) { - if constexpr (std::is_same_v || - std::is_same_v) { +template parser::Label GetErr(const A &stmt) { + if constexpr (std::is_same_v || + std::is_same_v) { for (const auto &control : stmt.controls) { if (std::holds_alternative(control.u)) { return std::get(control.u).v; } } } - if constexpr (std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v) { + if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { for (const auto &spec : stmt.v) { if (std::holds_alternative(spec.u)) { return std::get(spec.u).v; } } } - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { for (const auto &spec : std::get>(stmt.u)) { if (std::holds_alternative(spec.u)) { return std::get(spec.u).v; @@ -124,16 +126,16 @@ template parser::Label GetErr(const T &stmt) { return 0; } -template parser::Label GetEor(const T &stmt) { - if constexpr (std::is_same_v || - std::is_same_v) { +template parser::Label GetEor(const A &stmt) { + if constexpr (std::is_same_v || + std::is_same_v) { for (const auto &control : stmt.controls) { if (std::holds_alternative(control.u)) { return std::get(control.u).v; } } } - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { for (const auto &waitSpec : stmt.v) { if (std::holds_alternative(waitSpec.u)) { return std::get(waitSpec.u).v; @@ -143,16 +145,16 @@ template parser::Label GetEor(const T &stmt) { return 0; } -template parser::Label GetEnd(const T &stmt) { - if constexpr (std::is_same_v || - std::is_same_v) { +template parser::Label GetEnd(const A &stmt) { + if constexpr (std::is_same_v || + std::is_same_v) { for (const auto &control : stmt.controls) { if (std::holds_alternative(control.u)) { return std::get(control.u).v; } } } - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { for (const auto &waitSpec : stmt.v) { if (std::holds_alternative(waitSpec.u)) { return std::get(waitSpec.u).v; @@ -168,7 +170,7 @@ void errLabelSpec(const A &s, std::list &ops, if (auto errLab{GetErr(s)}) { std::optional errRef{FetchLabel(ad, errLab).get()}; LabelOp next{BuildNewLabel(ad)}; - ops.emplace_back(SwitchIOOp{s, next, errRef}); + ops.emplace_back(SwitchIOOp{s, next, ec.source, errRef}); ops.emplace_back(next); } else { ops.emplace_back(ActionOp{ec}); @@ -195,7 +197,7 @@ void threeLabelSpec(const A &s, std::list &ops, endRef = FetchLabel(ad, endLab).get(); } auto next{BuildNewLabel(ad)}; - ops.emplace_back(SwitchIOOp{s, next, errRef, eorRef, endRef}); + ops.emplace_back(SwitchIOOp{s, next, ec.source, errRef, eorRef, endRef}); ops.emplace_back(next); } else { ops.emplace_back(ActionOp{ec}); @@ -212,7 +214,7 @@ std::vector toLabelRef(AnalysisData &ad, const A &labels) { return result; } -bool hasAltReturns(const parser::CallStmt &callStmt) { +static bool hasAltReturns(const parser::CallStmt &callStmt) { const auto &args{std::get>(callStmt.v.t)}; for (const auto &arg : args) { const auto &actual{std::get(arg.t)}; @@ -223,7 +225,7 @@ bool hasAltReturns(const parser::CallStmt &callStmt) { return false; } -std::list getAltReturnLabels(const parser::Call &call) { +static std::list getAltReturnLabels(const parser::Call &call) { std::list result; const auto &args{std::get>(call.t)}; for (const auto &arg : args) { @@ -235,7 +237,7 @@ std::list getAltReturnLabels(const parser::Call &call) { return result; } -LabelRef NearestEnclosingDoConstruct(AnalysisData &ad) { +static LabelRef NearestEnclosingDoConstruct(AnalysisData &ad) { for (auto iterator{ad.nameStack.rbegin()}, endIterator{ad.nameStack.rend()}; iterator != endIterator; ++iterator) { auto labelReference{std::get<2>(*iterator)}; @@ -261,26 +263,15 @@ void GotoOp::dump() const { DebugChannel() << "\tgoto " << target << " [" << std::visit( common::visitors{ - [](const parser::CycleStmt *s) { return "CYCLE"s; }, - [](const parser::ExitStmt *s) { return "EXIT"s; }, - [](const parser::GotoStmt *s) { return "GOTO"s; }, [](ArtificialJump) { return ""s; }, + [&](const auto *) { return GetSource(this); }, }, u) << "]\n"; } void ReturnOp::dump() const { - DebugChannel() - << "\treturn [" - << std::visit( - common::visitors{ - [](const parser::FailImageStmt *s) { return "FAIL IMAGE"s; }, - [](const parser::ReturnStmt *s) { return "RETURN"s; }, - [](const parser::StopStmt *s) { return "STOP"s; }, - }, - u) - << "]\n"; + DebugChannel() << "\treturn [" << GetSource(this) << "]\n"; } void ConditionalGotoOp::dump() const { @@ -294,7 +285,7 @@ void ConditionalGotoOp::dump() const { [](const parser::Statement *s) { return GetSource(s); }, - [](const parser::IfStmt *s) { return ""s; }, + [](const parser::IfStmt *) { return "if-stmt"s; }, [](const parser::Statement *s) { return GetSource(s); }, @@ -314,49 +305,11 @@ void SwitchIOOp::dump() const { if (endLabel.has_value()) { DebugChannel() << " END:" << endLabel.value(); } - DebugChannel() - << " [" - << std::visit( - common::visitors{ - [](const parser::ReadStmt *) { return "READ"s; }, - [](const parser::WriteStmt *) { return "WRITE"s; }, - [](const parser::WaitStmt *) { return "WAIT"s; }, - [](const parser::OpenStmt *) { return "OPEN"s; }, - [](const parser::CloseStmt *) { return "CLOSE"s; }, - [](const parser::BackspaceStmt *) { return "BACKSPACE"s; }, - [](const parser::EndfileStmt *) { return "ENDFILE"s; }, - [](const parser::RewindStmt *) { return "REWIND"s; }, - [](const parser::FlushStmt *) { return "FLUSH"s; }, - [](const parser::InquireStmt *) { return "INQUIRE"s; }, - }, - u) - << "]\n"; + DebugChannel() << " [" << GetSource(this) << "]\n"; } void SwitchOp::dump() const { - DebugChannel() - << "\tswitch [" - << std::visit( - common::visitors{ - [](const parser::CaseConstruct *c) { - return GetSource(c); - }, - [](const parser::SelectRankConstruct *c) { - return GetSource(c); - }, - [](const parser::SelectTypeConstruct *c) { - return GetSource(c); - }, - [](const parser::ComputedGotoStmt *) { - return "computed GOTO"s; - }, - [](const parser::ArithmeticIfStmt *) { - return "arithmetic IF"s; - }, - [](const parser::CallStmt *) { return "alt-return CALL"s; }, - }, - u) - << "]\n"; + DebugChannel() << "\tswitch [" << GetSource(this) << "]\n"; } void ActionOp::dump() const { DebugChannel() << '\t' << GetSource(v) << '\n'; } @@ -405,8 +358,8 @@ void BeginOp::dump() const { [](const parser::CompilerDirective *c) { return GetSource(c); }, - [](const parser::OpenMPConstruct *c) { return "openmp"s; }, - [](const parser::OpenMPEndLoopDirective *c) { + [](const parser::OpenMPConstruct *) { return "openmp"s; }, + [](const parser::OpenMPEndLoopDirective *) { return "openmp end loop"s; }, }, @@ -415,53 +368,54 @@ void BeginOp::dump() const { } void EndOp::dump() const { - DebugChannel() - << "\t}: [" - << std::visit( - common::visitors{ - [](const parser::AssociateConstruct *c) { - return GetSource(c); - }, - [](const parser::BlockConstruct *c) { - return GetSource(c); - }, - [](const parser::CaseConstruct *c) { - return GetSource(c); - }, - [](const parser::ChangeTeamConstruct *c) { - return GetSource(c); - }, - [](const parser::CriticalConstruct *c) { - return GetSource(c); - }, - [](const parser::DoConstruct *c) { - return GetSource(c); - }, - [](const parser::IfConstruct *c) { - return GetSource(c); - }, - [](const parser::SelectRankConstruct *c) { - return GetSource(c); - }, - [](const parser::SelectTypeConstruct *c) { - return GetSource(c); - }, - [](const parser::WhereConstruct *c) { - return GetSource(c); - }, - [](const parser::ForallConstruct *c) { - return GetSource(c); - }, - [](const parser::CompilerDirective *c) { - return GetSource(c); - }, - [](const parser::OpenMPConstruct *c) { return "openmp"s; }, - [](const parser::OpenMPEndLoopDirective *c) { - return "openmp end loop"s; - }, - }, - u) - << "]\n"; + DebugChannel() << "\t}: [" + << std::visit( + common::visitors{ + [](const parser::AssociateConstruct *c) { + return GetSource(c); + }, + [](const parser::BlockConstruct *c) { + return GetSource(c); + }, + [](const parser::CaseConstruct *c) { + return GetSource(c); + }, + [](const parser::ChangeTeamConstruct *c) { + return GetSource(c); + }, + [](const parser::CriticalConstruct *c) { + return GetSource(c); + }, + [](const parser::DoConstruct *c) { + return GetSource(c); + }, + [](const parser::IfConstruct *c) { + return GetSource(c); + }, + [](const parser::SelectRankConstruct *c) { + return GetSource(c); + }, + [](const parser::SelectTypeConstruct *c) { + return GetSource(c); + }, + [](const parser::WhereConstruct *c) { + return GetSource(c); + }, + [](const parser::ForallConstruct *c) { + return GetSource(c); + }, + [](const parser::CompilerDirective *c) { + return GetSource(c); + }, + [](const parser::OpenMPConstruct *) { + return "openmp"s; + }, + [](const parser::OpenMPEndLoopDirective *) { + return "openmp end loop"s; + }, + }, + u) + << "]\n"; } void IndirectGotoOp::dump() const { @@ -473,13 +427,13 @@ void IndirectGotoOp::dump() const { } void DoIncrementOp::dump() const { - DebugChannel() << "\tincrement ["; - DebugChannel() << "]\n"; + using A = parser::Statement; + DebugChannel() << "\tincrement [" << GetSource(&std::get(v->t)) << "]\n"; } void DoCompareOp::dump() const { - DebugChannel() << "\tcompare ["; - DebugChannel() << "]\n"; + using A = parser::Statement; + DebugChannel() << "\tcompare [" << GetSource(&std::get(v->t)) << "]\n"; } void Op::Build(std::list &ops, @@ -492,7 +446,8 @@ void Op::Build(std::list &ops, auto next{BuildNewLabel(ad)}; auto labels{toLabelRef(ad, getAltReturnLabels(s.value().v))}; labels.push_back(next); - ops.emplace_back(SwitchOp{s.value(), std::move(labels)}); + ops.emplace_back( + SwitchOp{s.value(), std::move(labels), ec.source}); ops.emplace_back(next); } else { ops.emplace_back(ActionOp{ec}); @@ -507,27 +462,29 @@ void Op::Build(std::list &ops, ops.emplace_back(GotoOp{s.value(), s.value().v ? std::get<2>(FindStack(ad.nameStack, &s.value().v.value())) - : NearestEnclosingDoConstruct(ad)}); + : NearestEnclosingDoConstruct(ad), + ec.source}); }, [&](const common::Indirection &s) { ops.emplace_back(GotoOp{s.value(), s.value().v ? std::get<1>(FindStack(ad.nameStack, &s.value().v.value())) - : NearestEnclosingDoConstruct(ad)}); + : NearestEnclosingDoConstruct(ad), + ec.source}); }, [&](const common::Indirection &s) { - ops.emplace_back( - GotoOp{s.value(), FetchLabel(ad, s.value().v).get()}); + ops.emplace_back(GotoOp{ + s.value(), FetchLabel(ad, s.value().v).get(), ec.source}); }, [&](const parser::FailImageStmt &s) { - ops.emplace_back(ReturnOp{s}); + ops.emplace_back(ReturnOp{s, ec.source}); }, [&](const common::Indirection &s) { - ops.emplace_back(ReturnOp{s.value()}); + ops.emplace_back(ReturnOp{s.value(), ec.source}); }, [&](const common::Indirection &s) { ops.emplace_back(ActionOp{ec}); - ops.emplace_back(ReturnOp{s.value()}); + ops.emplace_back(ReturnOp{s.value(), ec.source}); }, [&](const common::Indirection &s) { threeLabelSpec(s.value(), ops, ec, ad); @@ -564,14 +521,15 @@ void Op::Build(std::list &ops, auto labels{toLabelRef( ad, std::get>(s.value().t))}; labels.push_back(next); - ops.emplace_back(SwitchOp{s.value(), std::move(labels)}); + ops.emplace_back(SwitchOp{s.value(), std::move(labels), ec.source}); ops.emplace_back(next); }, [&](const common::Indirection &s) { ops.emplace_back(SwitchOp{s.value(), toLabelRef(ad, std::list{std::get<1>(s.value().t), - std::get<2>(s.value().t), std::get<3>(s.value().t)})}); + std::get<2>(s.value().t), std::get<3>(s.value().t)}), + ec.source}); }, [&](const common::Indirection &s) { ops.emplace_back( @@ -760,7 +718,8 @@ struct ControlFlowAnalyzer { for (i = 0; i != N; ++i) { targets.emplace_back(GetLabelRef(toLabels[i])); } - ops.emplace_back(SwitchOp{construct, targets}); + ops.emplace_back( + SwitchOp{construct, targets, std::get<0>(construct.t).source}); ControlFlowAnalyzer cfa{ops, ad}; i = 0; for (const auto &caseBlock : std::get>(construct.t)) { diff --git a/flang/lib/FIR/flattened.h b/flang/lib/FIR/flattened.h index 01ea15e..de6e7aa 100644 --- a/flang/lib/FIR/flattened.h +++ b/flang/lib/FIR/flattened.h @@ -50,6 +50,7 @@ struct DoCompareOp; using LabelRef = unsigned; constexpr LabelRef unspecifiedLabel{~0u}; +using Location = parser::CharBlock; struct LabelBuilder; // target for a control-flow edge @@ -76,21 +77,24 @@ struct GotoOp : public SumTypeCopyMixin { template - GotoOp(const A &stmt, LabelRef dest) - : SumTypeCopyMixin{&stmt}, target{dest} {} - GotoOp(LabelRef dest) : SumTypeCopyMixin{ARTIFICIAL}, target{dest} {} + GotoOp(const A &stmt, LabelRef dest, const Location &source) + : SumTypeCopyMixin{&stmt}, target{dest}, source{source} {} + explicit GotoOp(LabelRef dest) : SumTypeCopyMixin{ARTIFICIAL}, target{dest} {} void dump() const; LabelRef target; + Location source; }; // control exits the procedure struct ReturnOp : public SumTypeCopyMixin { - SUM_TYPE_COPY_MIXIN(ReturnOp) + template + ReturnOp(const A &stmt, const Location &source) + : SumTypeCopyMixin{&stmt}, source{source} {} void dump() const; - template ReturnOp(const A &stmt) : SumTypeCopyMixin{&stmt} {} + Location source; }; // two-way branch based on a condition @@ -126,14 +130,16 @@ struct SwitchIOOp const parser::EndfileStmt *, const parser::RewindStmt *, const parser::FlushStmt *, const parser::InquireStmt *> { template - SwitchIOOp(const A &io, LabelRef next, std::optional errLab, + SwitchIOOp(const A &io, LabelRef next, const Location &source, + std::optional errLab, std::optional eorLab = std::nullopt, std::optional endLab = std::nullopt) - : SumTypeCopyMixin{&io}, next{next}, errLabel{errLab}, eorLabel{eorLab}, - endLabel{endLab} {} + : SumTypeCopyMixin{&io}, next{next}, source{source}, errLabel{errLab}, + eorLabel{eorLab}, endLabel{endLab} {} void dump() const; LabelRef next; + Location source; std::optional errLabel; std::optional eorLabel; std::optional endLabel; @@ -146,11 +152,13 @@ struct SwitchOp const parser::CaseConstruct *, const parser::SelectRankConstruct *, const parser::SelectTypeConstruct *> { template - SwitchOp(const A &sw, const std::vector &refs) - : SumTypeCopyMixin{&sw}, refs{refs} {} + SwitchOp( + const A &sw, const std::vector &refs, const Location &source) + : SumTypeCopyMixin{&sw}, refs{refs}, source{source} {} void dump() const; const std::vector refs; + Location source; }; // a compute step diff --git a/flang/lib/FIR/mixin.h b/flang/lib/FIR/mixin.h index 2d9e7b7..0304b9e 100644 --- a/flang/lib/FIR/mixin.h +++ b/flang/lib/FIR/mixin.h @@ -72,8 +72,7 @@ template struct ProductTypeMixin { }; // implementation of a (moveable) maybe type -template -struct MaybeMixin { +template struct MaybeMixin { MaybeMixin(T &&x) : o{std::move(x)} {} using MaybeTrait = std::true_type; MaybeMixin(MaybeMixin &&) = default; diff --git a/flang/lib/FIR/statements.h b/flang/lib/FIR/statements.h index b7e8498..cbc1751 100644 --- a/flang/lib/FIR/statements.h +++ b/flang/lib/FIR/statements.h @@ -605,9 +605,7 @@ inline std::list succ_list(BasicBlock &block) { return {}; } -inline Statement *ReturnStmt::value() const { - return Statement::From(value_); -} +inline Statement *ReturnStmt::value() const { return Statement::From(value_); } inline ApplyExprStmt *GetApplyExpr(Statement *stmt) { return std::get_if(&stmt->u);