Skip to content

Commit 70f8d46

Browse files
committed
debugging failure
1 parent 7b65ac4 commit 70f8d46

File tree

11 files changed

+199
-110
lines changed

11 files changed

+199
-110
lines changed

flang/include/flang/Lower/OpenACC.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,16 @@ class FirOpBuilder;
3737
}
3838

3939
namespace Fortran {
40+
namespace evaluate {
41+
class ProcedureDesignator;
42+
} // namespace evaluate
43+
4044
namespace parser {
4145
struct AccClauseList;
4246
struct OpenACCConstruct;
4347
struct OpenACCDeclarativeConstruct;
4448
struct OpenACCRoutineConstruct;
49+
struct ProcedureDesignator;
4550
} // namespace parser
4651

4752
namespace semantics {
@@ -71,6 +76,8 @@ static constexpr llvm::StringRef declarePostDeallocSuffix =
7176

7277
static constexpr llvm::StringRef privatizationRecipePrefix = "privatization";
7378

79+
bool needsOpenACCRoutineConstruct(const Fortran::evaluate::ProcedureDesignator *);
80+
7481
mlir::Value genOpenACCConstruct(AbstractConverter &,
7582
Fortran::semantics::SemanticsContext &,
7683
pft::Evaluation &,

flang/include/flang/Semantics/symbol.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <list>
2323
#include <optional>
2424
#include <set>
25+
#include <variant>
2526
#include <vector>
2627

2728
namespace llvm {
@@ -139,25 +140,26 @@ class OpenACCRoutineDeviceTypeInfo {
139140
void set_isGang(bool value = true) { isGang_ = value; }
140141
unsigned gangDim() const { return gangDim_; }
141142
void set_gangDim(unsigned value) { gangDim_ = value; }
142-
const std::string *bindName() const {
143-
return bindName_ ? &*bindName_ : nullptr;
143+
const std::variant<std::string, SymbolRef> *bindName() const {
144+
return bindName_.has_value() ? &*bindName_ : nullptr;
144145
}
145-
bool bindNameIsInternal() const {return bindNameIsInternal_;}
146-
void set_bindName(std::string &&name, bool isInternal=false) {
147-
bindName_ = std::move(name);
148-
bindNameIsInternal_ = isInternal;
146+
const std::optional<std::variant<std::string, SymbolRef>> &bindNameOpt() const {
147+
return bindName_;
149148
}
149+
void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
150+
void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
150151

151152
Fortran::common::OpenACCDeviceType dType() const { return deviceType_; }
152153

154+
friend llvm::raw_ostream &operator<<(
155+
llvm::raw_ostream &, const OpenACCRoutineDeviceTypeInfo &);
153156
private:
154157
bool isSeq_{false};
155158
bool isVector_{false};
156159
bool isWorker_{false};
157160
bool isGang_{false};
158161
unsigned gangDim_{0};
159-
std::optional<std::string> bindName_;
160-
bool bindNameIsInternal_{false};
162+
std::optional<std::variant<std::string, SymbolRef>> bindName_;
161163
Fortran::common::OpenACCDeviceType deviceType_{
162164
Fortran::common::OpenACCDeviceType::None};
163165
};
@@ -187,6 +189,9 @@ class OpenACCRoutineInfo : public OpenACCRoutineDeviceTypeInfo {
187189
return deviceTypeInfos_.back();
188190
}
189191

192+
friend llvm::raw_ostream &operator<<(
193+
llvm::raw_ostream &, const OpenACCRoutineInfo &);
194+
190195
private:
191196
std::list<OpenACCRoutineDeviceTypeInfo> deviceTypeInfos_;
192197
bool isNohost_{false};

flang/lib/Lower/Bridge.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -438,14 +438,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
438438
[&](Fortran::lower::pft::ModuleLikeUnit &m) { lowerMod(m); },
439439
[&](Fortran::lower::pft::BlockDataUnit &b) {},
440440
[&](Fortran::lower::pft::CompilerDirectiveUnit &d) {},
441-
[&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {
442-
builder = new fir::FirOpBuilder(
443-
bridge.getModule(), bridge.getKindMap(), &mlirSymbolTable);
444-
Fortran::lower::genOpenACCRoutineConstruct(
445-
*this, bridge.getSemanticsContext(), bridge.getModule(),
446-
d.routine);
447-
builder = nullptr;
448-
},
441+
[&](Fortran::lower::pft::OpenACCDirectiveUnit &d) {},
449442
},
450443
u);
451444
}
@@ -472,6 +465,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
472465
/// Declare a function.
473466
void declareFunction(Fortran::lower::pft::FunctionLikeUnit &funit) {
474467
setCurrentPosition(funit.getStartingSourceLoc());
468+
builder = new fir::FirOpBuilder(
469+
bridge.getModule(), bridge.getKindMap(), &mlirSymbolTable);
475470
for (int entryIndex = 0, last = funit.entryPointList.size();
476471
entryIndex < last; ++entryIndex) {
477472
funit.setActiveEntry(entryIndex);
@@ -498,6 +493,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
498493
for (Fortran::lower::pft::ContainedUnit &unit : funit.containedUnitList)
499494
if (auto *f = std::get_if<Fortran::lower::pft::FunctionLikeUnit>(&unit))
500495
declareFunction(*f);
496+
builder = nullptr;
501497
}
502498

503499
/// Get the scope that is defining or using \p sym. The returned scope is not
@@ -1035,7 +1031,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
10351031
return bridge.getSemanticsContext().FindScope(currentPosition);
10361032
}
10371033

1038-
fir::FirOpBuilder &getFirOpBuilder() override final { return *builder; }
1034+
fir::FirOpBuilder &getFirOpBuilder() override final {
1035+
CHECK(builder && "builder is not set before calling getFirOpBuilder");
1036+
return *builder;
1037+
}
10391038

10401039
mlir::ModuleOp getModuleOp() override final { return bridge.getModule(); }
10411040

@@ -5617,6 +5616,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
56175616
LLVM_DEBUG(llvm::dbgs() << "\n[bridge - startNewFunction]";
56185617
if (auto *sym = scope.symbol()) llvm::dbgs() << " " << *sym;
56195618
llvm::dbgs() << "\n");
5619+
// I don't think setting the builder is necessary here, because callee
5620+
// always looks up the FuncOp from the module. If there was a function that
5621+
// was not declared yet. This call to callee will cause an assertion
5622+
//failure.
56205623
Fortran::lower::CalleeInterface callee(funit, *this);
56215624
mlir::func::FuncOp func = callee.addEntryBlockAndMapArguments();
56225625
builder =

flang/lib/Lower/CallInterface.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "flang/Evaluate/fold.h"
1111
#include "flang/Lower/Bridge.h"
1212
#include "flang/Lower/Mangler.h"
13+
#include "flang/Lower/OpenACC.h"
1314
#include "flang/Lower/PFTBuilder.h"
1415
#include "flang/Lower/StatementContext.h"
1516
#include "flang/Lower/Support/Utils.h"
@@ -20,6 +21,7 @@
2021
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
2122
#include "flang/Optimizer/Support/InternalNames.h"
2223
#include "flang/Optimizer/Support/Utils.h"
24+
#include "flang/Parser/parse-tree.h"
2325
#include "flang/Semantics/symbol.h"
2426
#include "flang/Semantics/tools.h"
2527
#include "flang/Support/Fortran.h"
@@ -715,6 +717,14 @@ void Fortran::lower::CallInterface<T>::declare() {
715717
func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes);
716718

717719
setCUDAAttributes(func, side().getProcedureSymbol(), characteristic);
720+
721+
if (const Fortran::semantics::Symbol *sym = side().getProcedureSymbol()) {
722+
if (const auto &info{sym->GetUltimate().detailsIf<Fortran::semantics::SubprogramDetails>()}) {
723+
if (!info->openACCRoutineInfos().empty()) {
724+
genOpenACCRoutineConstruct(converter, module, func, info->openACCRoutineInfos());
725+
}
726+
}
727+
}
718728
}
719729
}
720730
}
@@ -1688,17 +1698,8 @@ class SignatureBuilder
16881698
fir::emitFatalError(converter.getCurrentLocation(),
16891699
"SignatureBuilder should only be used once");
16901700
declare();
1701+
16911702
interfaceDetermined = true;
1692-
if (procDesignator && procDesignator->GetInterfaceSymbol() &&
1693-
procDesignator->GetInterfaceSymbol()
1694-
->has<Fortran::semantics::SubprogramDetails>()) {
1695-
auto info = procDesignator->GetInterfaceSymbol()
1696-
->get<Fortran::semantics::SubprogramDetails>();
1697-
if (!info.openACCRoutineInfos().empty()) {
1698-
genOpenACCRoutineConstruct(converter, converter.getModuleOp(),
1699-
getFuncOp(), info.openACCRoutineInfos());
1700-
}
1701-
}
17021703
return getFuncOp();
17031704
}
17041705

flang/lib/Lower/OpenACC.cpp

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/Frontend/OpenACC/ACC.h.inc"
3737
#include "llvm/Support/CommandLine.h"
3838
#include "llvm/Support/Debug.h"
39+
#include "llvm/Support/ErrorHandling.h"
3940
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
4041
#include "mlir/IR/MLIRContext.h"
4142
#include "mlir/Support/LLVM.h"
@@ -4140,6 +4141,14 @@ static void attachRoutineInfo(mlir::func::FuncOp func,
41404141
mlir::acc::RoutineInfoAttr::get(func.getContext(), routines));
41414142
}
41424143

4144+
static mlir::ArrayAttr getArrayAttrOrNull(fir::FirOpBuilder &builder, llvm::SmallVector<mlir::Attribute> &attributes) {
4145+
if (attributes.empty()) {
4146+
return nullptr;
4147+
} else {
4148+
return builder.getArrayAttr(attributes);
4149+
}
4150+
}
4151+
41434152
void createOpenACCRoutineConstruct(
41444153
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
41454154
mlir::ModuleOp mod, mlir::func::FuncOp funcOp, std::string funcName,
@@ -4173,31 +4182,29 @@ void createOpenACCRoutineConstruct(
41734182
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
41744183
modBuilder.create<mlir::acc::RoutineOp>(
41754184
loc, routineOpStr, funcName,
4176-
bindNames.empty() ? nullptr : builder.getArrayAttr(bindNames),
4177-
bindNameDeviceTypes.empty() ? nullptr
4178-
: builder.getArrayAttr(bindNameDeviceTypes),
4179-
workerDeviceTypes.empty() ? nullptr
4180-
: builder.getArrayAttr(workerDeviceTypes),
4181-
vectorDeviceTypes.empty() ? nullptr
4182-
: builder.getArrayAttr(vectorDeviceTypes),
4183-
seqDeviceTypes.empty() ? nullptr : builder.getArrayAttr(seqDeviceTypes),
4185+
getArrayAttrOrNull(builder, bindNames),
4186+
getArrayAttrOrNull(builder, bindNameDeviceTypes),
4187+
getArrayAttrOrNull(builder, workerDeviceTypes),
4188+
getArrayAttrOrNull(builder, vectorDeviceTypes),
4189+
getArrayAttrOrNull(builder, seqDeviceTypes),
41844190
hasNohost, /*implicit=*/false,
4185-
gangDeviceTypes.empty() ? nullptr : builder.getArrayAttr(gangDeviceTypes),
4186-
gangDimValues.empty() ? nullptr : builder.getArrayAttr(gangDimValues),
4187-
gangDimDeviceTypes.empty() ? nullptr
4188-
: builder.getArrayAttr(gangDimDeviceTypes));
4189-
4190-
if (funcOp)
4191-
attachRoutineInfo(funcOp, builder.getSymbolRefAttr(routineOpStr));
4192-
else
4191+
getArrayAttrOrNull(builder, gangDeviceTypes),
4192+
getArrayAttrOrNull(builder, gangDimValues),
4193+
getArrayAttrOrNull(builder, gangDimDeviceTypes));
4194+
4195+
auto symbolRefAttr = builder.getSymbolRefAttr(routineOpStr);
4196+
if (funcOp) {
4197+
4198+
attachRoutineInfo(funcOp, symbolRefAttr);
4199+
} else {
41934200
// FuncOp is not lowered yet. Keep the information so the routine info
41944201
// can be attached later to the funcOp.
4195-
converter.getAccDelayedRoutines().push_back(
4196-
std::make_pair(funcName, builder.getSymbolRefAttr(routineOpStr)));
4202+
converter.getAccDelayedRoutines().push_back(std::make_pair(funcName, symbolRefAttr));
4203+
}
41974204
}
41984205

41994206
static void interpretRoutineDeviceInfo(
4200-
fir::FirOpBuilder &builder,
4207+
Fortran::lower::AbstractConverter &converter,
42014208
const Fortran::semantics::OpenACCRoutineDeviceTypeInfo &dinfo,
42024209
llvm::SmallVector<mlir::Attribute> &seqDeviceTypes,
42034210
llvm::SmallVector<mlir::Attribute> &vectorDeviceTypes,
@@ -4207,23 +4214,24 @@ static void interpretRoutineDeviceInfo(
42074214
llvm::SmallVector<mlir::Attribute> &gangDeviceTypes,
42084215
llvm::SmallVector<mlir::Attribute> &gangDimValues,
42094216
llvm::SmallVector<mlir::Attribute> &gangDimDeviceTypes) {
4210-
mlir::MLIRContext *context{builder.getContext()};
4217+
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
4218+
auto getDeviceTypeAttr = [&]() -> mlir::Attribute {
4219+
auto context = builder.getContext();
4220+
auto value = getDeviceType(dinfo.dType());
4221+
return mlir::acc::DeviceTypeAttr::get(context, value );
4222+
};
42114223
if (dinfo.isSeq()) {
4212-
seqDeviceTypes.push_back(
4213-
mlir::acc::DeviceTypeAttr::get(context, getDeviceType(dinfo.dType())));
4224+
seqDeviceTypes.push_back(getDeviceTypeAttr());
42144225
}
42154226
if (dinfo.isVector()) {
4216-
vectorDeviceTypes.push_back(
4217-
mlir::acc::DeviceTypeAttr::get(context, getDeviceType(dinfo.dType())));
4227+
vectorDeviceTypes.push_back(getDeviceTypeAttr());
42184228
}
42194229
if (dinfo.isWorker()) {
4220-
workerDeviceTypes.push_back(
4221-
mlir::acc::DeviceTypeAttr::get(context, getDeviceType(dinfo.dType())));
4230+
workerDeviceTypes.push_back(getDeviceTypeAttr());
42224231
}
42234232
if (dinfo.isGang()) {
42244233
unsigned gangDim = dinfo.gangDim();
4225-
auto deviceType =
4226-
mlir::acc::DeviceTypeAttr::get(context, getDeviceType(dinfo.dType()));
4234+
auto deviceType = getDeviceTypeAttr();
42274235
if (!gangDim) {
42284236
gangDeviceTypes.push_back(deviceType);
42294237
} else {
@@ -4232,10 +4240,18 @@ static void interpretRoutineDeviceInfo(
42324240
gangDimDeviceTypes.push_back(deviceType);
42334241
}
42344242
}
4235-
if (const std::string *bindName{dinfo.bindName()}) {
4236-
bindNames.push_back(builder.getStringAttr(*bindName));
4237-
bindNameDeviceTypes.push_back(
4238-
mlir::acc::DeviceTypeAttr::get(context, getDeviceType(dinfo.dType())));
4243+
if (dinfo.bindNameOpt().has_value()) {
4244+
const auto &bindName = dinfo.bindNameOpt().value();
4245+
mlir::Attribute bindNameAttr;
4246+
if (const auto &bindStr{std::get_if<std::string>(&bindName)}) {
4247+
bindNameAttr = builder.getStringAttr(*bindStr);
4248+
} else if (const auto &bindSym{std::get_if<Fortran::semantics::SymbolRef>(&bindName)}) {
4249+
bindNameAttr = builder.getStringAttr(converter.mangleName(*bindSym));
4250+
} else {
4251+
llvm_unreachable("Unsupported bind name type");
4252+
}
4253+
bindNames.push_back(bindNameAttr);
4254+
bindNameDeviceTypes.push_back(getDeviceTypeAttr());
42394255
}
42404256
}
42414257

@@ -4244,7 +4260,6 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42444260
mlir::func::FuncOp funcOp,
42454261
const std::vector<Fortran::semantics::OpenACCRoutineInfo> &routineInfos) {
42464262
CHECK(funcOp && "Expected a valid function operation");
4247-
fir::FirOpBuilder &builder{converter.getFirOpBuilder()};
42484263
mlir::Location loc{funcOp.getLoc()};
42494264
std::string funcName{funcOp.getName()};
42504265

@@ -4262,7 +4277,7 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42624277
}
42634278
// Note: Device Independent Attributes are set to the
42644279
// none device type in `info`.
4265-
interpretRoutineDeviceInfo(builder, info, seqDeviceTypes, vectorDeviceTypes,
4280+
interpretRoutineDeviceInfo(converter, info, seqDeviceTypes, vectorDeviceTypes,
42664281
workerDeviceTypes, bindNameDeviceTypes,
42674282
bindNames, gangDeviceTypes, gangDimValues,
42684283
gangDimDeviceTypes);
@@ -4271,7 +4286,7 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42714286
for (const Fortran::semantics::OpenACCRoutineDeviceTypeInfo &dinfo :
42724287
info.deviceTypeInfos()) {
42734288
interpretRoutineDeviceInfo(
4274-
builder, dinfo, seqDeviceTypes, vectorDeviceTypes, workerDeviceTypes,
4289+
converter, dinfo, seqDeviceTypes, vectorDeviceTypes, workerDeviceTypes,
42754290
bindNameDeviceTypes, bindNames, gangDeviceTypes, gangDimValues,
42764291
gangDimDeviceTypes);
42774292
}
@@ -4369,8 +4384,6 @@ void Fortran::lower::genOpenACCRoutineConstruct(
43694384
std::get_if<Fortran::parser::AccClause::Bind>(&clause.u)) {
43704385
if (const auto *name =
43714386
std::get_if<Fortran::parser::Name>(&bindClause->v.u)) {
4372-
// FIXME: This case mangles the name, the one below does not.
4373-
// which is correct?
43744387
mlir::Attribute bindNameAttr =
43754388
builder.getStringAttr(converter.mangleName(*name->symbol));
43764389
for (auto crtDeviceTypeAttr : crtDeviceTypes) {

flang/lib/Semantics/mod-file.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <fstream>
2525
#include <set>
2626
#include <string_view>
27+
#include <variant>
2728
#include <vector>
2829

2930
namespace Fortran::semantics {
@@ -638,8 +639,14 @@ static void PutOpenACCDeviceTypeRoutineInfo(
638639
if (info.isWorker()) {
639640
os << " worker";
640641
}
641-
if (info.bindName()) {
642-
os << " bind(" << *info.bindName() << ")";
642+
if (const std::variant<std::string, SymbolRef> *bindName{info.bindName()}) {
643+
os << " bind(";
644+
if (std::holds_alternative<std::string>(*bindName)) {
645+
os << "\"" << std::get<std::string>(*bindName) << "\"";
646+
} else {
647+
os << std::get<SymbolRef>(*bindName)->name();
648+
}
649+
os << ")";
643650
}
644651
}
645652

0 commit comments

Comments
 (0)