|
35 | 35 | #include "flang/Optimizer/Builder/Runtime/Stop.h"
|
36 | 36 | #include "flang/Optimizer/Builder/Runtime/Transformational.h"
|
37 | 37 | #include "flang/Optimizer/Builder/Todo.h"
|
| 38 | +#include "flang/Optimizer/Dialect/FIROps.h" |
38 | 39 | #include "flang/Optimizer/Dialect/FIROpsSupport.h"
|
39 | 40 | #include "flang/Optimizer/Dialect/Support/FIRContext.h"
|
40 | 41 | #include "flang/Optimizer/Support/FatalError.h"
|
|
49 | 50 | #include "llvm/Support/Debug.h"
|
50 | 51 | #include "llvm/Support/MathExtras.h"
|
51 | 52 | #include "llvm/Support/raw_ostream.h"
|
| 53 | +#include <mlir/IR/Value.h> |
52 | 54 | #include <optional>
|
53 | 55 |
|
54 | 56 | #define DEBUG_TYPE "flang-lower-intrinsic"
|
@@ -1681,6 +1683,24 @@ IntrinsicLibrary::genElementalCall<IntrinsicLibrary::SubroutineGenerator>(
|
1681 | 1683 | return mlir::Value();
|
1682 | 1684 | }
|
1683 | 1685 |
|
| 1686 | +template <> |
| 1687 | +fir::ExtendedValue |
| 1688 | +IntrinsicLibrary::genElementalCall<IntrinsicLibrary::DualGenerator>( |
| 1689 | + DualGenerator generator, llvm::StringRef name, mlir::Type resultType, |
| 1690 | + llvm::ArrayRef<fir::ExtendedValue> args, bool outline) { |
| 1691 | + assert(resultType.getImpl() && "expect elemental intrinsic to be functions"); |
| 1692 | + |
| 1693 | + for (const fir::ExtendedValue &arg : args) |
| 1694 | + if (!arg.getUnboxed() && !arg.getCharBox()) |
| 1695 | + // fir::emitFatalError(loc, "nonscalar intrinsic argument"); |
| 1696 | + crashOnMissingIntrinsic(loc, name); |
| 1697 | + if (outline) |
| 1698 | + return outlineInExtendedWrapper(generator, name, resultType, args); |
| 1699 | + |
| 1700 | + return std::invoke(generator, *this, std::optional<mlir::Type>{resultType}, |
| 1701 | + args); |
| 1702 | +} |
| 1703 | + |
1684 | 1704 | static fir::ExtendedValue
|
1685 | 1705 | invokeHandler(IntrinsicLibrary::ElementalGenerator generator,
|
1686 | 1706 | const IntrinsicHandler &handler,
|
@@ -1724,6 +1744,22 @@ invokeHandler(IntrinsicLibrary::SubroutineGenerator generator,
|
1724 | 1744 | return mlir::Value{};
|
1725 | 1745 | }
|
1726 | 1746 |
|
| 1747 | +static fir::ExtendedValue |
| 1748 | +invokeHandler(IntrinsicLibrary::DualGenerator generator, |
| 1749 | + const IntrinsicHandler &handler, |
| 1750 | + std::optional<mlir::Type> resultType, |
| 1751 | + llvm::ArrayRef<fir::ExtendedValue> args, bool outline, |
| 1752 | + IntrinsicLibrary &lib) { |
| 1753 | + if (handler.isElemental) |
| 1754 | + return lib.genElementalCall(generator, handler.name, mlir::Type{}, args, |
| 1755 | + outline); |
| 1756 | + if (outline) |
| 1757 | + return lib.outlineInExtendedWrapper(generator, handler.name, resultType, |
| 1758 | + args); |
| 1759 | + |
| 1760 | + return std::invoke(generator, lib, resultType, args); |
| 1761 | +} |
| 1762 | + |
1727 | 1763 | std::pair<fir::ExtendedValue, bool>
|
1728 | 1764 | IntrinsicLibrary::genIntrinsicCall(llvm::StringRef specificName,
|
1729 | 1765 | std::optional<mlir::Type> resultType,
|
@@ -1819,6 +1855,34 @@ IntrinsicLibrary::invokeGenerator(SubroutineGenerator generator,
|
1819 | 1855 | return {};
|
1820 | 1856 | }
|
1821 | 1857 |
|
| 1858 | +mlir::Value |
| 1859 | +IntrinsicLibrary::invokeGenerator(DualGenerator generator, |
| 1860 | + llvm::ArrayRef<mlir::Value> args) { |
| 1861 | + llvm::SmallVector<fir::ExtendedValue> extendedArgs; |
| 1862 | + for (mlir::Value arg : args) |
| 1863 | + extendedArgs.emplace_back(toExtendedValue(arg, builder, loc)); |
| 1864 | + std::invoke(generator, *this, std::optional<mlir::Type>{}, extendedArgs); |
| 1865 | + return {}; |
| 1866 | +} |
| 1867 | + |
| 1868 | +mlir::Value |
| 1869 | +IntrinsicLibrary::invokeGenerator(DualGenerator generator, |
| 1870 | + mlir::Type resultType, |
| 1871 | + llvm::ArrayRef<mlir::Value> args) { |
| 1872 | + llvm::SmallVector<fir::ExtendedValue> extendedArgs; |
| 1873 | + for (mlir::Value arg : args) |
| 1874 | + extendedArgs.emplace_back(toExtendedValue(arg, builder, loc)); |
| 1875 | + |
| 1876 | + if (resultType.getImpl() == nullptr) { |
| 1877 | + // TODO: |
| 1878 | + assert(false && "result type is null"); |
| 1879 | + } |
| 1880 | + |
| 1881 | + auto extendedResult = std::invoke( |
| 1882 | + generator, *this, std::optional<mlir::Type>{resultType}, extendedArgs); |
| 1883 | + return toValue(extendedResult, builder, loc); |
| 1884 | +} |
| 1885 | + |
1822 | 1886 | //===----------------------------------------------------------------------===//
|
1823 | 1887 | // Intrinsic Procedure Mangling
|
1824 | 1888 | //===----------------------------------------------------------------------===//
|
@@ -3235,18 +3299,34 @@ void IntrinsicLibrary::genExecuteCommandLine(
|
3235 | 3299 | }
|
3236 | 3300 |
|
3237 | 3301 | // ETIME
|
3238 |
| -void IntrinsicLibrary::genEtime(llvm::ArrayRef<fir::ExtendedValue> args) { |
3239 |
| - assert(args.size() == 2); |
| 3302 | +fir::ExtendedValue |
| 3303 | +IntrinsicLibrary::genEtime(std::optional<mlir::Type> resultType, |
| 3304 | + llvm::ArrayRef<fir::ExtendedValue> args) { |
| 3305 | + assert((args.size() == 2 && !resultType.has_value()) || |
| 3306 | + (args.size() == 1 && resultType.has_value())); |
3240 | 3307 |
|
3241 | 3308 | mlir::Value values = fir::getBase(args[0]);
|
3242 |
| - mlir::Value time = fir::getBase(args[1]); |
3243 |
| - |
3244 |
| - if (!values) |
3245 |
| - fir::emitFatalError(loc, "expected VALUES parameter"); |
3246 |
| - if (!time) |
3247 |
| - fir::emitFatalError(loc, "expected TIME parameter"); |
3248 |
| - |
3249 |
| - fir::runtime::genEtime(builder, loc, values, time); |
| 3309 | + if (resultType.has_value()) { |
| 3310 | + // function form |
| 3311 | + if (!values) |
| 3312 | + fir::emitFatalError(loc, "expected VALUES parameter"); |
| 3313 | + |
| 3314 | + auto timeAddr = builder.createTemporary(loc, *resultType); |
| 3315 | + auto timeBox = builder.createBox(loc, timeAddr); |
| 3316 | + fir::runtime::genEtime(builder, loc, values, timeBox); |
| 3317 | + return builder.create<fir::LoadOp>(loc, timeAddr); |
| 3318 | + } else { |
| 3319 | + // subroutine form |
| 3320 | + mlir::Value time = fir::getBase(args[1]); |
| 3321 | + if (!values) |
| 3322 | + fir::emitFatalError(loc, "expected VALUES parameter"); |
| 3323 | + if (!time) |
| 3324 | + fir::emitFatalError(loc, "expected TIME parameter"); |
| 3325 | + |
| 3326 | + fir::runtime::genEtime(builder, loc, values, time); |
| 3327 | + return {}; |
| 3328 | + } |
| 3329 | + return {}; |
3250 | 3330 | }
|
3251 | 3331 |
|
3252 | 3332 | // EXIT
|
|
0 commit comments