Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions flang/include/flang/Lower/AbstractConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,21 @@ class AbstractConverter {
/// added or replaced at the inner-most level of the local symbol map.
virtual void bindSymbol(SymbolRef sym, const fir::ExtendedValue &exval) = 0;

/// Binds the symbol's physical storage to a storage descriptor,
/// which is the base address of the storage and the offset
/// within the storage, where the symbol begins.
/// The symbol binding will be added or replaced at the innermost level
/// of the local symbol map.
virtual void
bindSymbolStorage(SymbolRef sym,
Fortran::lower::SymMap::StorageDesc storage) = 0;

/// Returns the storage descriptor previously bound to this symbol.
/// If there is no bound storage, the descriptor will contain
/// nullptr base address.
virtual Fortran::lower::SymMap::StorageDesc
getSymbolStorage(SymbolRef sym) = 0;

/// Override lowering of expression with pre-lowered values.
/// Associate mlir::Value to evaluate::Expr. All subsequent call to
/// genExprXXX() will replace any occurrence of an overridden
Expand Down
6 changes: 5 additions & 1 deletion flang/include/flang/Lower/ConvertVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,14 @@ void defineCommonBlocks(
/// 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.
/// \p commonSize specifies the syze of the COMMON block in bytes.
/// The size is used to represent a COMMON block reference as
/// a !fir.ref<!fir.array<SIZExi8>>.
mlir::Value genCommonBlockMember(AbstractConverter &converter,
mlir::Location loc,
const Fortran::semantics::Symbol &sym,
mlir::Value commonValue);
mlir::Value commonValue,
std::size_t commonSize);

/// 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
Expand Down
26 changes: 25 additions & 1 deletion flang/include/flang/Lower/SymbolMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,22 @@ struct SymbolBox : public fir::details::matcher<SymbolBox> {
class SymMap {
public:
using AcDoVar = llvm::StringRef;
/// Descriptor of a symbol's storage consists of the base address
/// of the storage and the offset within that storage.
using StorageDesc = std::pair<mlir::Value, std::uint64_t>;

SymMap() { pushScope(); }
SymMap(const SymMap &) = delete;

void pushScope() { symbolMapStack.emplace_back(); }
void pushScope() {
symbolMapStack.emplace_back();
storageMapStack.emplace_back();
}
void popScope() {
symbolMapStack.pop_back();
assert(symbolMapStack.size() >= 1);
storageMapStack.pop_back();
assert(storageMapStack.size() >= 1);
}

/// Add an extended value to the symbol table.
Expand Down Expand Up @@ -287,6 +295,8 @@ class SymMap {
symbolMapStack.emplace_back();
assert(symbolMapStack.size() == 1);
impliedDoStack.clear();
storageMapStack.clear();
storageMapStack.emplace_back();
}

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
Expand Down Expand Up @@ -315,6 +325,16 @@ class SymMap {
return std::nullopt;
}

/// Register the symbol's storage at the innermost level
/// of the symbol table. If the storage is already registered,
/// it will be replaced.
void registerStorage(semantics::SymbolRef sym, StorageDesc storage);
/// Lookup the symbol's storage at the innermost level of the symbol table.
StorageDesc lookupStorage(semantics::SymbolRef sym);
StorageDesc lookupStorage(const semantics::Symbol *sym) {
return lookupStorage(*sym);
}

private:
/// Bind `box` to `symRef` in the symbol map.
void makeSym(semantics::SymbolRef symRef, const SymbolBox &box,
Expand All @@ -332,6 +352,10 @@ class SymMap {
// Implied DO induction variables are not represented as Se::Symbol in
// Ev::Expr. Keep the variable markers in their own stack.
llvm::SmallVector<std::pair<AcDoVar, mlir::Value>> impliedDoStack;

// A stack of maps between the symbols and their storage descriptors.
llvm::SmallVector<llvm::DenseMap<const semantics::Symbol *, StorageDesc>>
storageMapStack;
};

/// RAII wrapper for SymMap.
Expand Down
3 changes: 2 additions & 1 deletion flang/include/flang/Optimizer/Builder/HLFIRTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ fir::FortranVariableOpInterface
genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
const fir::ExtendedValue &exv, llvm::StringRef name,
fir::FortranVariableFlagsAttr flags,
mlir::Value dummyScope = nullptr,
mlir::Value dummyScope = nullptr, mlir::Value storage = nullptr,
std::uint64_t storageOffset = 0,
cuf::DataAttributeAttr dataAttr = {});

/// Generate an hlfir.associate to build a variable from an expression value.
Expand Down
8 changes: 5 additions & 3 deletions flang/include/flang/Optimizer/HLFIR/HLFIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,12 @@ def hlfir_DeclareOp
attr-dict `:` functional-type(operands, results)
}];

let builders = [
OpBuilder<(ins "mlir::Value":$memref, "llvm::StringRef":$uniq_name,
CArg<"mlir::Value", "{}">:$shape, CArg<"mlir::ValueRange", "{}">:$typeparams,
let builders = [OpBuilder<(ins "mlir::Value":$memref,
"llvm::StringRef":$uniq_name, CArg<"mlir::Value", "{}">:$shape,
CArg<"mlir::ValueRange", "{}">:$typeparams,
CArg<"mlir::Value", "{}">:$dummy_scope,
CArg<"mlir::Value", "{}">:$storage,
CArg<"std::uint64_t", "0">:$storage_offset,
CArg<"fir::FortranVariableFlagsAttr", "{}">:$fortran_attrs,
CArg<"cuf::DataAttributeAttr", "{}">:$data_attr)>];

Expand Down
11 changes: 11 additions & 0 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,17 @@ class FirConverter : public Fortran::lower::AbstractConverter {
addSymbol(sym, exval, /*forced=*/true);
}

void bindSymbolStorage(
Fortran::lower::SymbolRef sym,
Fortran::lower::SymMap::StorageDesc storage) override final {
localSymbols.registerStorage(sym, std::move(storage));
}

Fortran::lower::SymMap::StorageDesc
getSymbolStorage(Fortran::lower::SymbolRef sym) override final {
return localSymbols.lookupStorage(sym);
}

void
overrideExprValues(const Fortran::lower::ExprToValueMap *map) override final {
exprValueOverrides = map;
Expand Down
5 changes: 2 additions & 3 deletions flang/lib/Lower/ConvertArrayConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,8 @@ class RuntimeTempStrategy : public StrategyBase {
mlir::Value tempStorage = builder.createHeapTemporary(
loc, declaredType, tempName, extents, lengths);
mlir::Value shape = builder.genShape(loc, extents);
declare = hlfir::DeclareOp::create(
builder, loc, tempStorage, tempName, shape, lengths,
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
declare = hlfir::DeclareOp::create(builder, loc, tempStorage, tempName,
shape, lengths);
initialBoxValue =
builder.createBox(loc, boxType, declare->getOriginalBase(), shape,
/*slice=*/mlir::Value{}, lengths, /*tdesc=*/{});
Expand Down
6 changes: 2 additions & 4 deletions flang/lib/Lower/ConvertExprToHLFIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1813,10 +1813,8 @@ class HlfirBuilder {
// Allocate scalar temporary that will be initialized
// with the values specified by the constructor.
mlir::Value storagePtr = builder.createTemporary(loc, recTy);
auto varOp = hlfir::EntityWithAttributes{hlfir::DeclareOp::create(
builder, loc, storagePtr, "ctor.temp", /*shape=*/nullptr,
/*typeparams=*/mlir::ValueRange{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{})};
auto varOp = hlfir::EntityWithAttributes{
hlfir::DeclareOp::create(builder, loc, storagePtr, "ctor.temp")};

// Initialize any components that need initialization.
mlir::Value box = builder.createBox(loc, fir::ExtendedValue{varOp});
Expand Down
28 changes: 19 additions & 9 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@ static void instantiateAlias(Fortran::lower::AbstractConverter &converter,
mlir::Value bytePtr = fir::CoordinateOp::create(
builder, loc, i8Ptr, storeAddr, mlir::ValueRange{offset});
mlir::Value typedPtr = castAliasToPointer(builder, loc, symType, bytePtr);
converter.bindSymbolStorage(sym, {storeAddr, off});
Fortran::lower::StatementContext stmtCtx;
mapSymbolAttributes(converter, var, symMap, stmtCtx, typedPtr);
// Default initialization is possible for equivalence members: see
Expand Down Expand Up @@ -1655,13 +1656,15 @@ void Fortran::lower::defineCommonBlocks(

mlir::Value Fortran::lower::genCommonBlockMember(
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const Fortran::semantics::Symbol &sym, mlir::Value commonValue) {
const Fortran::semantics::Symbol &sym, mlir::Value commonValue,
std::size_t commonSize) {
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));
fir::SequenceType::Shape shape(1, commonSize);
mlir::Type seqTy = builder.getRefType(fir::SequenceType::get(shape, i8Ty));
mlir::Value base = builder.createConvert(loc, seqTy, commonValue);

mlir::Value offs =
Expand All @@ -1670,6 +1673,8 @@ mlir::Value Fortran::lower::genCommonBlockMember(
mlir::ValueRange{offs});
mlir::Type symType = converter.genType(sym);

converter.bindSymbolStorage(sym, {base, byteOffset});

return Fortran::semantics::FindEquivalenceSet(sym) != nullptr
? castAliasToPointer(builder, loc, symType, varAddr)
: builder.createConvert(loc, builder.getRefType(symType), varAddr);
Expand Down Expand Up @@ -1698,7 +1703,8 @@ static void instantiateCommon(Fortran::lower::AbstractConverter &converter,
symMap.addSymbol(common, commonAddr);
}

mlir::Value local = genCommonBlockMember(converter, loc, varSym, commonAddr);
mlir::Value local =
genCommonBlockMember(converter, loc, varSym, commonAddr, common.size());
Fortran::lower::StatementContext stmtCtx;
mapSymbolAttributes(converter, var, symMap, stmtCtx, local);
}
Expand Down Expand Up @@ -1970,7 +1976,8 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
// Declare a local pointer variable.
auto newBase = hlfir::DeclareOp::create(
builder, loc, boxAlloc, name, /*shape=*/nullptr, lenParams,
/*dummy_scope=*/nullptr, attributes);
/*dummy_scope=*/nullptr, /*storage=*/nullptr,
/*storage_offset=*/0, attributes);
mlir::Value nullAddr = builder.createNullConstant(
loc, llvm::cast<fir::BaseBoxType>(ptrBoxType).getEleTy());

Expand Down Expand Up @@ -2000,9 +2007,10 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
mlir::Value dummyScope;
if (converter.isRegisteredDummySymbol(sym))
dummyScope = converter.dummyArgsScopeValue();
auto newBase =
hlfir::DeclareOp::create(builder, loc, base, name, shapeOrShift,
lenParams, dummyScope, attributes, dataAttr);
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
auto newBase = hlfir::DeclareOp::create(
builder, loc, base, name, shapeOrShift, lenParams, dummyScope, storage,
storageOffset, attributes, dataAttr);
symMap.addVariableDefinition(sym, newBase, force);
return;
}
Expand Down Expand Up @@ -2060,8 +2068,10 @@ void Fortran::lower::genDeclareSymbol(
base = genPackArray(converter, sym, exv);
dummyScope = converter.dummyArgsScopeValue();
}
hlfir::EntityWithAttributes declare = hlfir::genDeclare(
loc, builder, base, name, attributes, dummyScope, dataAttr);
auto [storage, storageOffset] = converter.getSymbolStorage(sym);
hlfir::EntityWithAttributes declare =
hlfir::genDeclare(loc, builder, base, name, attributes, dummyScope,
storage, storageOffset, dataAttr);
symMap.addVariableDefinition(sym, declare.getIfVariableInterface(), force);
return;
}
Expand Down
18 changes: 6 additions & 12 deletions flang/lib/Lower/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,12 +1212,10 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(

auto leftDeclOp = hlfir::DeclareOp::create(
builder, loc, recipe.getCopyRegion().getArgument(0), llvm::StringRef{},
shape, llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
shape);
auto rightDeclOp = hlfir::DeclareOp::create(
builder, loc, recipe.getCopyRegion().getArgument(1), llvm::StringRef{},
shape, llvm::ArrayRef<mlir::Value>{}, /*dummy_scope=*/nullptr,
fir::FortranVariableFlagsAttr{});
shape);

hlfir::DesignateOp::Subscripts triplets =
getSubscriptsFromArgs(recipe.getCopyRegion().getArguments());
Expand Down Expand Up @@ -1523,14 +1521,10 @@ static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
auto shape =
genShapeFromBoundsOrArgs(loc, builder, seqTy, bounds,
recipe.getCombinerRegion().getArguments());
auto v1DeclareOp = hlfir::DeclareOp::create(
builder, loc, value1, llvm::StringRef{}, shape,
llvm::ArrayRef<mlir::Value>{},
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
auto v2DeclareOp = hlfir::DeclareOp::create(
builder, loc, value2, llvm::StringRef{}, shape,
llvm::ArrayRef<mlir::Value>{},
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
auto v1DeclareOp = hlfir::DeclareOp::create(builder, loc, value1,
llvm::StringRef{}, shape);
auto v2DeclareOp = hlfir::DeclareOp::create(builder, loc, value2,
llvm::StringRef{}, shape);
hlfir::DesignateOp::Subscripts triplets = getTripletsFromArgs(recipe);

llvm::SmallVector<mlir::Value> lenParamsLeft;
Expand Down
6 changes: 4 additions & 2 deletions flang/lib/Lower/OpenMP/ClauseProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -847,10 +847,12 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter,
}
auto declDst = hlfir::DeclareOp::create(
builder, loc, dst, copyFuncName + "_dst", shape, typeparams,
/*dummy_scope=*/nullptr, attrs);
/*dummy_scope=*/nullptr, /*storage=*/nullptr,
/*storage_offset=*/0, attrs);
auto declSrc = hlfir::DeclareOp::create(
builder, loc, src, copyFuncName + "_src", shape, typeparams,
/*dummy_scope=*/nullptr, attrs);
/*dummy_scope=*/nullptr, /*storage=*/nullptr,
/*storage_offset=*/0, attrs);
converter.copyVar(loc, declDst.getBase(), declSrc.getBase(), varAttrs);
mlir::func::ReturnOp::create(builder, loc);
return funcOp;
Expand Down
9 changes: 5 additions & 4 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ static void threadPrivatizeVars(lower::AbstractConverter &converter,
}
symThreadprivateValue = lower::genCommonBlockMember(
converter, currentLocation, sym->GetUltimate(),
commonThreadprivateValue);
commonThreadprivateValue, common->size());
} else {
symThreadprivateValue = genThreadprivateOp(*sym);
}
Expand Down Expand Up @@ -1401,7 +1401,7 @@ static void genIntermediateCommonBlockAccessors(

for (auto obj : details->objects()) {
auto targetCBMemberBind = Fortran::lower::genCommonBlockMember(
converter, currentLocation, *obj, mapArg);
converter, currentLocation, *obj, mapArg, mapSym->size());
fir::ExtendedValue sexv = converter.getSymbolExtendedValue(*obj);
fir::ExtendedValue targetCBExv =
getExtendedValue(sexv, targetCBMemberBind);
Expand Down Expand Up @@ -4086,8 +4086,9 @@ void Fortran::lower::genThreadprivateOp(lower::AbstractConverter &converter,
firOpBuilder, currentLocation, commonValue.getType(), commonValue);
converter.bindSymbol(*common, commonThreadprivateValue);
// Generate the threadprivate value for the common block member.
symThreadprivateValue = genCommonBlockMember(converter, currentLocation,
sym, commonThreadprivateValue);
symThreadprivateValue =
genCommonBlockMember(converter, currentLocation, sym,
commonThreadprivateValue, common->size());
} 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
17 changes: 17 additions & 0 deletions flang/lib/Lower/SymbolMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
return {};
}

void Fortran::lower::SymMap::registerStorage(
semantics::SymbolRef symRef, Fortran::lower::SymMap::StorageDesc storage) {
auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
assert(storage.first && "registerting storage without an address");
storageMapStack.back().insert_or_assign(sym, std::move(storage));
}

Fortran::lower::SymMap::StorageDesc
Fortran::lower::SymMap::lookupStorage(Fortran::semantics::SymbolRef symRef) {
auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
auto &map = storageMapStack.back();
auto iter = map.find(sym);
if (iter != map.end())
return iter->second;
return {nullptr, 0};
}

void Fortran::lower::SymbolBox::dump() const { llvm::errs() << *this << '\n'; }

void Fortran::lower::SymMap::dump() const { llvm::errs() << *this << '\n'; }
Expand Down
Loading