Skip to content

Commit

Permalink
[flang] Move genCommonBlockMember from OpenMP to ConvertVariable, N…
Browse files Browse the repository at this point in the history
…FC (#74488)

The function `genCommonBlockMember` is not specific to OpenMP, and it
could very well be a common utility. Move it to ConvertVariable.cpp
where it logically belongs.
  • Loading branch information
kparzysz committed Dec 6, 2023
1 parent 02c218c commit 10f7801
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 46 deletions.
19 changes: 17 additions & 2 deletions flang/include/flang/Lower/ConvertVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "flang/Lower/Support/Utils.h"
#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Semantics/symbol.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/DenseMap.h"

Expand All @@ -29,7 +30,12 @@ class GlobalOp;
class FortranVariableFlagsAttr;
} // namespace fir

namespace Fortran ::lower {
namespace Fortran {
namespace semantics {
class Scope;
} // namespace semantics

namespace lower {
class AbstractConverter;
class CallerInterface;
class StatementContext;
Expand Down Expand Up @@ -66,6 +72,14 @@ void defineCommonBlocks(
const std::vector<std::pair<semantics::SymbolRef, std::size_t>>
&commonBlocks);

/// The COMMON block is a global structure. \p commonValue is the base address
/// of the COMMON block. As the offset from the symbol \p sym, generate the
/// COMMON block member value (commonValue + offset) for the symbol.
mlir::Value genCommonBlockMember(AbstractConverter &converter,
mlir::Location loc,
const Fortran::semantics::Symbol &sym,
mlir::Value commonValue);

/// Lower a symbol attributes given an optional storage \p and add it to the
/// provided symbol map. If \preAlloc is not provided, a temporary storage will
/// be allocated. This is a low level function that should only be used if
Expand Down Expand Up @@ -138,5 +152,6 @@ void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
/// Cray pointer symbol. Assert if the pointer symbol cannot be found.
Fortran::semantics::SymbolRef getCrayPointer(Fortran::semantics::SymbolRef sym);

} // namespace Fortran::lower
} // namespace lower
} // namespace Fortran
#endif // FORTRAN_LOWER_CONVERT_VARIABLE_H
39 changes: 24 additions & 15 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,28 @@ void Fortran::lower::defineCommonBlocks(
finalizeCommonBlockDefinition(loc, converter, global, cmnBlkMems);
}

mlir::Value Fortran::lower::genCommonBlockMember(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const Fortran::semantics::Symbol &sym, mlir::Value commonValue) {
fir::FirOpBuilder &builder = converter.getFirOpBuilder();

std::size_t byteOffset = sym.GetUltimate().offset();
mlir::IntegerType i8Ty = builder.getIntegerType(8);
mlir::Type i8Ptr = builder.getRefType(i8Ty);
mlir::Type seqTy = builder.getRefType(builder.getVarLenSeqTy(i8Ty));
mlir::Value base = builder.createConvert(loc, seqTy, commonValue);

mlir::Value offs =
builder.createIntegerConstant(loc, builder.getIndexType(), byteOffset);
mlir::Value varAddr = builder.create<fir::CoordinateOp>(
loc, i8Ptr, base, mlir::ValueRange{offs});
mlir::Type symType = converter.genType(sym);

return Fortran::semantics::FindEquivalenceSet(sym) != nullptr
? castAliasToPointer(builder, loc, symType, varAddr)
: builder.createConvert(loc, builder.getRefType(symType), varAddr);
}

/// The COMMON block is a global structure. `var` will be at some offset
/// within the COMMON block. Adds the address of `var` (COMMON + offset) to
/// the symbol map.
Expand All @@ -1353,21 +1375,8 @@ static void instantiateCommon(Fortran::lower::AbstractConverter &converter,

symMap.addSymbol(common, commonAddr);
}
std::size_t byteOffset = varSym.GetUltimate().offset();
mlir::IntegerType i8Ty = builder.getIntegerType(8);
mlir::Type i8Ptr = builder.getRefType(i8Ty);
mlir::Type seqTy = builder.getRefType(builder.getVarLenSeqTy(i8Ty));
mlir::Value base = builder.createConvert(loc, seqTy, commonAddr);
mlir::Value offs =
builder.createIntegerConstant(loc, builder.getIndexType(), byteOffset);
auto varAddr = builder.create<fir::CoordinateOp>(loc, i8Ptr, base,
mlir::ValueRange{offs});
mlir::Type symType = converter.genType(var.getSymbol());
mlir::Value local;
if (Fortran::semantics::FindEquivalenceSet(var.getSymbol()) != nullptr)
local = castAliasToPointer(builder, loc, symType, varAddr);
else
local = builder.createConvert(loc, builder.getRefType(symType), varAddr);

mlir::Value local = genCommonBlockMember(converter, loc, varSym, commonAddr);
Fortran::lower::StatementContext stmtCtx;
mapSymbolAttributes(converter, var, symMap, stmtCtx, local);
}
Expand Down
33 changes: 4 additions & 29 deletions flang/lib/Lower/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1959,31 +1959,6 @@ static mlir::Operation *getCompareFromReductionOp(mlir::Operation *reductionOp,
return nullptr;
}

/// The COMMON block is a global structure. \p commonValue is the base address
/// of the COMMON block. As the offset from the symbol \p sym, generate the
/// COMMON block member value (commonValue + offset) for the symbol.
/// FIXME: Share the code with `instantiateCommon` in ConvertVariable.cpp.
static mlir::Value
genCommonBlockMember(Fortran::lower::AbstractConverter &converter,
const Fortran::semantics::Symbol &sym,
mlir::Value commonValue) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::Location currentLocation = converter.getCurrentLocation();
mlir::IntegerType i8Ty = firOpBuilder.getIntegerType(8);
mlir::Type i8Ptr = firOpBuilder.getRefType(i8Ty);
mlir::Type seqTy = firOpBuilder.getRefType(firOpBuilder.getVarLenSeqTy(i8Ty));
mlir::Value base =
firOpBuilder.createConvert(currentLocation, seqTy, commonValue);
std::size_t byteOffset = sym.GetUltimate().offset();
mlir::Value offs = firOpBuilder.createIntegerConstant(
currentLocation, firOpBuilder.getIndexType(), byteOffset);
mlir::Value varAddr = firOpBuilder.create<fir::CoordinateOp>(
currentLocation, i8Ptr, base, mlir::ValueRange{offs});
mlir::Type symType = converter.genType(sym);
return firOpBuilder.createConvert(currentLocation,
firOpBuilder.getRefType(symType), varAddr);
}

// Get the extended value for \p val by extracting additional variable
// information from \p base.
static fir::ExtendedValue getExtendedValue(fir::ExtendedValue base,
Expand Down Expand Up @@ -2049,8 +2024,8 @@ static void threadPrivatizeVars(Fortran::lower::AbstractConverter &converter,
converter.bindSymbol(*common, commonThreadprivateValue);
commonSyms.insert(common);
}
symThreadprivateValue =
genCommonBlockMember(converter, *sym, commonThreadprivateValue);
symThreadprivateValue = Fortran::lower::genCommonBlockMember(
converter, currentLocation, *sym, commonThreadprivateValue);
} else {
symThreadprivateValue = genThreadprivateOp(*sym);
}
Expand Down Expand Up @@ -3554,8 +3529,8 @@ void Fortran::lower::genThreadprivateOp(
currentLocation, commonValue.getType(), commonValue);
converter.bindSymbol(*common, commonThreadprivateValue);
// Generate the threadprivate value for the common block member.
symThreadprivateValue =
genCommonBlockMember(converter, sym, commonThreadprivateValue);
symThreadprivateValue = genCommonBlockMember(converter, currentLocation,
sym, commonThreadprivateValue);
} else if (!var.isGlobal()) {
// Non-global variable which can be in threadprivate directive must be one
// variable in main program, and it has implicit SAVE attribute. Take it as
Expand Down

0 comments on commit 10f7801

Please sign in to comment.