mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 23:36:06 +00:00
[flang][debug] Support assumed shape arrays. (#94644)
This PR generates dwarf to extract the information about the arrays from descriptor. The DWARF needs the offset of the fields like `lower_bound` and `extent`. The getComponentOffset has been added to calculate them which pushes the issue of host and target data size into getDescFieldTypeModel. As we use data layout now, some tests needed to be adjusted to have a dummy data layout to avoid failure. With this change in place, GDB is able show the assumed shape arrays correctly. subroutine ff(n, m, arr) integer n, m integer :: arr(:, :) print *, arr do i = 1, n do j = 1, m arr(j, i) = (i * 5) + j + 10 end do end do print *, arr end subroutine ff Breakpoint 1, ff (n=4, m=3, arr=...) at test1.f90:13 13 print *, arr (gdb) p arr $1 = ((6, 7, 8, 9) (11, 12, 13, 14) (16, 17, 18, 19)) (gdb) ptype arr type = integer (4,3) (gdb) c Continuing. 6 7 8 9 11 12 13 14 16 17 18 19
This commit is contained in:
parent
4cff320e0d
commit
b64cf381a7
@ -35,73 +35,73 @@ using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *);
|
|||||||
|
|
||||||
/// Get the LLVM IR dialect model for building a particular C++ type, `T`.
|
/// Get the LLVM IR dialect model for building a particular C++ type, `T`.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TypeBuilderFunc getModel();
|
static TypeBuilderFunc getModel();
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<void *>() {
|
constexpr TypeBuilderFunc getModel<void *>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::LLVM::LLVMPointerType::get(context);
|
return mlir::LLVM::LLVMPointerType::get(context);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<unsigned>() {
|
constexpr TypeBuilderFunc getModel<unsigned>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(unsigned) * 8);
|
return mlir::IntegerType::get(context, sizeof(unsigned) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<int>() {
|
constexpr TypeBuilderFunc getModel<int>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(int) * 8);
|
return mlir::IntegerType::get(context, sizeof(int) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<unsigned long>() {
|
constexpr TypeBuilderFunc getModel<unsigned long>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(unsigned long) * 8);
|
return mlir::IntegerType::get(context, sizeof(unsigned long) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<unsigned long long>() {
|
constexpr TypeBuilderFunc getModel<unsigned long long>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(unsigned long long) * 8);
|
return mlir::IntegerType::get(context, sizeof(unsigned long long) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<long long>() {
|
constexpr TypeBuilderFunc getModel<long long>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(long long) * 8);
|
return mlir::IntegerType::get(context, sizeof(long long) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<Fortran::ISO::CFI_rank_t>() {
|
constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_rank_t>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context,
|
return mlir::IntegerType::get(context,
|
||||||
sizeof(Fortran::ISO::CFI_rank_t) * 8);
|
sizeof(Fortran::ISO::CFI_rank_t) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<Fortran::ISO::CFI_type_t>() {
|
constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_type_t>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context,
|
return mlir::IntegerType::get(context,
|
||||||
sizeof(Fortran::ISO::CFI_type_t) * 8);
|
sizeof(Fortran::ISO::CFI_type_t) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<long>() {
|
constexpr TypeBuilderFunc getModel<long>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
return mlir::IntegerType::get(context, sizeof(long) * 8);
|
return mlir::IntegerType::get(context, sizeof(long) * 8);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc getModel<Fortran::ISO::CFI_dim_t>() {
|
constexpr TypeBuilderFunc getModel<Fortran::ISO::CFI_dim_t>() {
|
||||||
return [](mlir::MLIRContext *context) -> mlir::Type {
|
return [](mlir::MLIRContext *context) -> mlir::Type {
|
||||||
auto indexTy = getModel<Fortran::ISO::CFI_index_t>()(context);
|
auto indexTy = getModel<Fortran::ISO::CFI_index_t>()(context);
|
||||||
return mlir::LLVM::LLVMArrayType::get(indexTy, 3);
|
return mlir::LLVM::LLVMArrayType::get(indexTy, 3);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
TypeBuilderFunc
|
constexpr TypeBuilderFunc
|
||||||
getModel<Fortran::ISO::cfi_internal::FlexibleArray<Fortran::ISO::CFI_dim_t>>() {
|
getModel<Fortran::ISO::cfi_internal::FlexibleArray<Fortran::ISO::CFI_dim_t>>() {
|
||||||
return getModel<Fortran::ISO::CFI_dim_t>();
|
return getModel<Fortran::ISO::CFI_dim_t>();
|
||||||
}
|
}
|
@ -13,9 +13,9 @@
|
|||||||
#define DEBUG_TYPE "flang-type-conversion"
|
#define DEBUG_TYPE "flang-type-conversion"
|
||||||
|
|
||||||
#include "flang/Optimizer/CodeGen/TypeConverter.h"
|
#include "flang/Optimizer/CodeGen/TypeConverter.h"
|
||||||
#include "DescriptorModel.h"
|
|
||||||
#include "flang/Common/Fortran.h"
|
#include "flang/Common/Fortran.h"
|
||||||
#include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done
|
#include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done
|
||||||
|
#include "flang/Optimizer/CodeGen/DescriptorModel.h"
|
||||||
#include "flang/Optimizer/CodeGen/TBAABuilder.h"
|
#include "flang/Optimizer/CodeGen/TBAABuilder.h"
|
||||||
#include "flang/Optimizer/CodeGen/Target.h"
|
#include "flang/Optimizer/CodeGen/Target.h"
|
||||||
#include "flang/Optimizer/Dialect/FIRType.h"
|
#include "flang/Optimizer/Dialect/FIRType.h"
|
||||||
|
@ -13,15 +13,55 @@
|
|||||||
#define DEBUG_TYPE "flang-debug-type-generator"
|
#define DEBUG_TYPE "flang-debug-type-generator"
|
||||||
|
|
||||||
#include "DebugTypeGenerator.h"
|
#include "DebugTypeGenerator.h"
|
||||||
|
#include "flang/Optimizer/CodeGen/DescriptorModel.h"
|
||||||
|
#include "flang/Optimizer/CodeGen/TypeConverter.h"
|
||||||
|
#include "flang/Optimizer/Support/DataLayout.h"
|
||||||
|
#include "mlir/Pass/Pass.h"
|
||||||
#include "llvm/ADT/ScopeExit.h"
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
|
||||||
namespace fir {
|
namespace fir {
|
||||||
|
|
||||||
|
/// Calculate offset of any field in the descriptor.
|
||||||
|
template <int DescriptorField>
|
||||||
|
std::uint64_t getComponentOffset(const mlir::DataLayout &dl,
|
||||||
|
mlir::MLIRContext *context,
|
||||||
|
mlir::Type llvmFieldType) {
|
||||||
|
static_assert(DescriptorField > 0 && DescriptorField < 10);
|
||||||
|
mlir::Type previousFieldType =
|
||||||
|
getDescFieldTypeModel<DescriptorField - 1>()(context);
|
||||||
|
std::uint64_t previousOffset =
|
||||||
|
getComponentOffset<DescriptorField - 1>(dl, context, previousFieldType);
|
||||||
|
std::uint64_t offset = previousOffset + dl.getTypeSize(previousFieldType);
|
||||||
|
std::uint64_t fieldAlignment = dl.getTypeABIAlignment(llvmFieldType);
|
||||||
|
return llvm::alignTo(offset, fieldAlignment);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
std::uint64_t getComponentOffset<0>(const mlir::DataLayout &dl,
|
||||||
|
mlir::MLIRContext *context,
|
||||||
|
mlir::Type llvmFieldType) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
|
DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
|
||||||
: module(m), kindMapping(getKindMapping(m)) {
|
: module(m), kindMapping(getKindMapping(m)) {
|
||||||
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
|
LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
|
||||||
|
|
||||||
|
std::optional<mlir::DataLayout> dl =
|
||||||
|
fir::support::getOrSetDataLayout(module, /*allowDefaultLayout=*/true);
|
||||||
|
if (!dl) {
|
||||||
|
mlir::emitError(module.getLoc(), "Missing data layout attribute in module");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mlir::MLIRContext *context = module.getContext();
|
||||||
|
|
||||||
|
// The debug information requires the offset of certain fields in the
|
||||||
|
// descriptors like lower_bound and extent for each dimension.
|
||||||
|
mlir::Type llvmDimsType = getDescFieldTypeModel<kDimsPosInBox>()(context);
|
||||||
|
dimsOffset = getComponentOffset<kDimsPosInBox>(*dl, context, llvmDimsType);
|
||||||
|
dimsSize = dl->getTypeSize(llvmDimsType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
|
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
|
||||||
@ -37,10 +77,82 @@ static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
|
|||||||
llvm::dwarf::DW_ATE_signed);
|
llvm::dwarf::DW_ATE_signed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(
|
||||||
|
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
|
||||||
|
mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated,
|
||||||
|
bool genAssociated) {
|
||||||
|
|
||||||
|
mlir::MLIRContext *context = module.getContext();
|
||||||
|
// FIXME: Assumed rank arrays not supported yet
|
||||||
|
if (seqTy.hasUnknownShape())
|
||||||
|
return genPlaceholderType(context);
|
||||||
|
|
||||||
|
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
|
||||||
|
auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
|
||||||
|
ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
|
||||||
|
};
|
||||||
|
|
||||||
|
addOp(llvm::dwarf::DW_OP_push_object_address, {});
|
||||||
|
addOp(llvm::dwarf::DW_OP_deref, {});
|
||||||
|
|
||||||
|
// dataLocation = *base_addr
|
||||||
|
mlir::LLVM::DIExpressionAttr dataLocation =
|
||||||
|
mlir::LLVM::DIExpressionAttr::get(context, ops);
|
||||||
|
addOp(llvm::dwarf::DW_OP_lit0, {});
|
||||||
|
addOp(llvm::dwarf::DW_OP_ne, {});
|
||||||
|
|
||||||
|
// allocated = associated = (*base_addr != 0)
|
||||||
|
mlir::LLVM::DIExpressionAttr valid =
|
||||||
|
mlir::LLVM::DIExpressionAttr::get(context, ops);
|
||||||
|
mlir::LLVM::DIExpressionAttr associated = genAllocated ? valid : nullptr;
|
||||||
|
mlir::LLVM::DIExpressionAttr allocated = genAssociated ? valid : nullptr;
|
||||||
|
ops.clear();
|
||||||
|
|
||||||
|
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
|
||||||
|
mlir::LLVM::DITypeAttr elemTy =
|
||||||
|
convertType(seqTy.getEleTy(), fileAttr, scope, loc);
|
||||||
|
unsigned offset = dimsOffset;
|
||||||
|
const unsigned indexSize = dimsSize / 3;
|
||||||
|
for ([[maybe_unused]] auto _ : seqTy.getShape()) {
|
||||||
|
// For each dimension, find the offset of count and lower bound in the
|
||||||
|
// descriptor and generate the dwarf expression to extract it.
|
||||||
|
// FIXME: If `indexSize` happens to be bigger than address size on the
|
||||||
|
// system then we may have to change 'DW_OP_deref' here.
|
||||||
|
addOp(llvm::dwarf::DW_OP_push_object_address, {});
|
||||||
|
addOp(llvm::dwarf::DW_OP_plus_uconst,
|
||||||
|
{offset + (indexSize * kDimExtentPos)});
|
||||||
|
addOp(llvm::dwarf::DW_OP_deref, {});
|
||||||
|
// count[i] = *(base_addr + offset + (indexSize * kDimExtentPos))
|
||||||
|
// where 'offset' is dimsOffset + (i * dimsSize)
|
||||||
|
mlir::LLVM::DIExpressionAttr countAttr =
|
||||||
|
mlir::LLVM::DIExpressionAttr::get(context, ops);
|
||||||
|
ops.clear();
|
||||||
|
|
||||||
|
addOp(llvm::dwarf::DW_OP_push_object_address, {});
|
||||||
|
addOp(llvm::dwarf::DW_OP_plus_uconst,
|
||||||
|
{offset + (indexSize * kDimLowerBoundPos)});
|
||||||
|
addOp(llvm::dwarf::DW_OP_deref, {});
|
||||||
|
// lower_bound[i] = *(base_addr + offset + (indexSize * kDimLowerBoundPos))
|
||||||
|
mlir::LLVM::DIExpressionAttr lowerAttr =
|
||||||
|
mlir::LLVM::DIExpressionAttr::get(context, ops);
|
||||||
|
ops.clear();
|
||||||
|
|
||||||
|
offset += dimsSize;
|
||||||
|
mlir::LLVM::DISubrangeAttr subrangeTy = mlir::LLVM::DISubrangeAttr::get(
|
||||||
|
context, nullptr, lowerAttr, countAttr, nullptr);
|
||||||
|
elements.push_back(subrangeTy);
|
||||||
|
}
|
||||||
|
return mlir::LLVM::DICompositeTypeAttr::get(
|
||||||
|
context, llvm::dwarf::DW_TAG_array_type, /*recursive id*/ {},
|
||||||
|
/* name */ nullptr, /* file */ nullptr, /* line */ 0,
|
||||||
|
/* scope */ nullptr, elemTy, mlir::LLVM::DIFlags::Zero,
|
||||||
|
/* sizeInBits */ 0, /*alignInBits*/ 0, elements, dataLocation,
|
||||||
|
/* rank */ nullptr, allocated, associated);
|
||||||
|
}
|
||||||
|
|
||||||
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
|
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
|
||||||
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
|
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
|
||||||
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
|
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
|
||||||
|
|
||||||
mlir::MLIRContext *context = module.getContext();
|
mlir::MLIRContext *context = module.getContext();
|
||||||
// FIXME: Only fixed sizes arrays handled at the moment.
|
// FIXME: Only fixed sizes arrays handled at the moment.
|
||||||
if (seqTy.hasDynamicExtents())
|
if (seqTy.hasDynamicExtents())
|
||||||
@ -112,6 +224,12 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
|
|||||||
bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
|
bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
|
||||||
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
|
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
|
||||||
return convertSequenceType(seqTy, fileAttr, scope, loc);
|
return convertSequenceType(seqTy, fileAttr, scope, loc);
|
||||||
|
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
|
||||||
|
auto elTy = boxTy.getElementType();
|
||||||
|
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
|
||||||
|
return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, false,
|
||||||
|
false);
|
||||||
|
return genPlaceholderType(context);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: These types are currently unhandled. We are generating a
|
// FIXME: These types are currently unhandled. We are generating a
|
||||||
// placeholder type to allow us to test supported bits.
|
// placeholder type to allow us to test supported bits.
|
||||||
|
@ -35,8 +35,20 @@ private:
|
|||||||
mlir::LLVM::DIFileAttr fileAttr,
|
mlir::LLVM::DIFileAttr fileAttr,
|
||||||
mlir::LLVM::DIScopeAttr scope,
|
mlir::LLVM::DIScopeAttr scope,
|
||||||
mlir::Location loc);
|
mlir::Location loc);
|
||||||
|
|
||||||
|
/// The 'genAllocated' is true when we want to generate 'allocated' field
|
||||||
|
/// in the DICompositeType. It is needed for the allocatable arrays.
|
||||||
|
/// Similarly, 'genAssociated' is used with 'pointer' type to generate
|
||||||
|
/// 'associated' field.
|
||||||
|
mlir::LLVM::DITypeAttr
|
||||||
|
convertBoxedSequenceType(fir::SequenceType seqTy,
|
||||||
|
mlir::LLVM::DIFileAttr fileAttr,
|
||||||
|
mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
|
||||||
|
bool genAllocated, bool genAssociated);
|
||||||
mlir::ModuleOp module;
|
mlir::ModuleOp module;
|
||||||
KindMapping kindMapping;
|
KindMapping kindMapping;
|
||||||
|
std::uint64_t dimsSize;
|
||||||
|
std::uint64_t dimsOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fir
|
} // namespace fir
|
||||||
|
13
flang/test/Integration/debug-assumed-shape-array.f90
Normal file
13
flang/test/Integration/debug-assumed-shape-array.f90
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
subroutine ff(arr)
|
||||||
|
implicit none
|
||||||
|
integer :: arr(:, :)
|
||||||
|
return arr(1,1)
|
||||||
|
end subroutine ff
|
||||||
|
|
||||||
|
! CHECK-DAG: !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS:[0-9]+]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
||||||
|
! CHECK-DAG: ![[ELEMS]] = !{![[ELEM1:[0-9]+]], ![[ELEM2:[0-9]+]]}
|
||||||
|
! CHECK-DAG: ![[ELEM1]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref))
|
||||||
|
! CHECK-DAG: ![[ELEM2]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// This test checks that debug information for fir.real type works ok.
|
// This test checks that debug information for fir.real type works ok.
|
||||||
|
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QPfn1(%arg0: !fir.ref<!fir.complex<8>> {fir.bindc_name = "a"} ) {
|
func.func @_QPfn1(%arg0: !fir.ref<!fir.complex<8>> {fir.bindc_name = "a"} ) {
|
||||||
%0 = fir.declare %arg0 {uniq_name = "_QFfn1Ea"} : (!fir.ref<!fir.complex<8>>) -> !fir.ref<!fir.complex<8>>
|
%0 = fir.declare %arg0 {uniq_name = "_QFfn1Ea"} : (!fir.ref<!fir.complex<8>>) -> !fir.ref<!fir.complex<8>>
|
||||||
%1 = fir.alloca f32 {bindc_name = "abserror", uniq_name = "_QFfn1Eabserror"}
|
%1 = fir.alloca f32 {bindc_name = "abserror", uniq_name = "_QFfn1Eabserror"}
|
||||||
|
16
flang/test/Transforms/debug-assumed-shape-array.fir
Normal file
16
flang/test/Transforms/debug-assumed-shape-array.fir
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
|
||||||
|
|
||||||
|
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"} {
|
||||||
|
func.func @ff_(%arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} ) {
|
||||||
|
%0 = fir.undefined !fir.dscope
|
||||||
|
%1 = fircg.ext_declare %arg0 dummy_scope %0 {uniq_name = "_QFffEarr"} : (!fir.box<!fir.array<?x?xi32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xi32>> loc(#loc1)
|
||||||
|
return
|
||||||
|
} loc(#loc2)
|
||||||
|
}
|
||||||
|
#loc1 = loc("test1.f90":1:1)
|
||||||
|
#loc2 = loc("test1.f90":3:16)
|
||||||
|
|
||||||
|
// CHECK: #llvm.di_composite_type<tag = DW_TAG_array_type
|
||||||
|
// CHECK-SAME: elements = #llvm.di_subrange<lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(24), DW_OP_deref]>, upperBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(32), DW_OP_deref]>>
|
||||||
|
// CHECK-SAME: #llvm.di_subrange<lowerBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(48), DW_OP_deref]>, upperBound = #llvm.di_expression<[DW_OP_push_object_address, DW_OP_plus_uconst(56), DW_OP_deref]>>
|
||||||
|
// CHECK-SAME: dataLocation = <[DW_OP_push_object_address, DW_OP_deref]>>
|
@ -3,7 +3,7 @@
|
|||||||
// check conversion of complex type of different size. Both fir and mlir
|
// check conversion of complex type of different size. Both fir and mlir
|
||||||
// variants are checked.
|
// variants are checked.
|
||||||
|
|
||||||
module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "native"} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @test1(%x : !fir.complex<4>) -> !fir.complex<8> {
|
func.func @test1(%x : !fir.complex<4>) -> !fir.complex<8> {
|
||||||
%1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<8>
|
%1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<8>
|
||||||
return %1 : !fir.complex<8>
|
return %1 : !fir.complex<8>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
|
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
|
||||||
|
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
|
func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
|
||||||
%c7 = arith.constant 7 : index
|
%c7 = arith.constant 7 : index
|
||||||
%c8 = arith.constant 8 : index
|
%c8 = arith.constant 8 : index
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// REQUIRES: system-linux
|
// REQUIRES: system-linux
|
||||||
|
|
||||||
// Test that there are no changes to a function with existed fused loc debug
|
// Test that there are no changes to a function with existed fused loc debug
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QPs1() {
|
func.func @_QPs1() {
|
||||||
return loc(#loc1)
|
return loc(#loc1)
|
||||||
} loc(#loc2)
|
} loc(#loc2)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// REQUIRES: system-linux
|
// REQUIRES: system-linux
|
||||||
|
|
||||||
// Test for included functions that have a different debug location than the current file
|
// Test for included functions that have a different debug location than the current file
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QPsinc() {
|
func.func @_QPsinc() {
|
||||||
return loc(#loc2)
|
return loc(#loc2)
|
||||||
} loc(#loc1)
|
} loc(#loc1)
|
||||||
@ -19,7 +19,7 @@ module attributes {} {
|
|||||||
#loc4 = loc("/home/user01/llvm-project/build_release/simple.f90":4:3)
|
#loc4 = loc("/home/user01/llvm-project/build_release/simple.f90":4:3)
|
||||||
#loc5 = loc("/home/user01/llvm-project/build_release/simple.f90":5:1)
|
#loc5 = loc("/home/user01/llvm-project/build_release/simple.f90":5:1)
|
||||||
|
|
||||||
// CHECK: module {
|
// CHECK: module
|
||||||
// CHECK: func.func @_QPsinc() {
|
// CHECK: func.func @_QPsinc() {
|
||||||
// CHECK: } loc(#[[FUSED_LOC_INC_FILE:.*]])
|
// CHECK: } loc(#[[FUSED_LOC_INC_FILE:.*]])
|
||||||
// CHECK: func.func @_QQmain() {
|
// CHECK: func.func @_QQmain() {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// Test that there is only one FileAttribute generated for multiple functions
|
// Test that there is only one FileAttribute generated for multiple functions
|
||||||
// in the same file.
|
// in the same file.
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QPs1() {
|
func.func @_QPs1() {
|
||||||
return loc(#loc2)
|
return loc(#loc2)
|
||||||
} loc(#loc1)
|
} loc(#loc1)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=LINETABLE
|
// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=LINETABLE
|
||||||
// RUN: fir-opt --add-debug-info="is-optimized=true" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=OPT
|
// RUN: fir-opt --add-debug-info="is-optimized=true" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=OPT
|
||||||
|
|
||||||
module attributes { fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", llvm.target_triple = "aarch64-unknown-linux-gnu"} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
func.func @_QPsb() {
|
func.func @_QPsb() {
|
||||||
return loc(#loc_sb)
|
return loc(#loc_sb)
|
||||||
} loc(#loc_sb)
|
} loc(#loc_sb)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
|
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
module attributes {} {
|
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
|
||||||
fir.global @_QMhelperEgli : i32 {
|
fir.global @_QMhelperEgli : i32 {
|
||||||
%0 = fir.zero_bits i32
|
%0 = fir.zero_bits i32
|
||||||
fir.has_value %0 : i32
|
fir.has_value %0 : i32
|
||||||
|
Loading…
x
Reference in New Issue
Block a user