Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
flang/lib/Lower/IntrinsicCall.cpp
Show First 20 Lines • Show All 762 Lines • ▼ Show 20 Lines | static constexpr IntrinsicHandler handlers[]{ | ||||
/*isElemental=*/false}, | /*isElemental=*/false}, | ||||
{"exponent", &I::genExponent}, | {"exponent", &I::genExponent}, | ||||
{"floor", &I::genFloor}, | {"floor", &I::genFloor}, | ||||
{"fraction", &I::genFraction}, | {"fraction", &I::genFraction}, | ||||
{"get_command_argument", | {"get_command_argument", | ||||
&I::genGetCommandArgument, | &I::genGetCommandArgument, | ||||
{{{"number", asValue}, | {{{"number", asValue}, | ||||
{"value", asBox, handleDynamicOptional}, | {"value", asBox, handleDynamicOptional}, | ||||
{"length", asAddr}, | {"length", asBox, handleDynamicOptional}, | ||||
{"status", asAddr}, | {"status", asAddr}, | ||||
jeanPerier: STATUS is also optional, I think it also needs to have `handleDynamicOptional` so that the… | |||||
{"errmsg", asBox, handleDynamicOptional}}}, | {"errmsg", asBox, handleDynamicOptional}}}, | ||||
/*isElemental=*/false}, | /*isElemental=*/false}, | ||||
{"get_environment_variable", | {"get_environment_variable", | ||||
&I::genGetEnvironmentVariable, | &I::genGetEnvironmentVariable, | ||||
{{{"name", asBox}, | {{{"name", asBox}, | ||||
{"value", asBox, handleDynamicOptional}, | {"value", asBox, handleDynamicOptional}, | ||||
{"length", asAddr}, | {"length", asAddr}, | ||||
{"status", asAddr}, | {"status", asAddr}, | ||||
▲ Show 20 Lines • Show All 1,990 Lines • ▼ Show 20 Lines | void IntrinsicLibrary::genGetCommandArgument( | ||||
const fir::ExtendedValue &value = args[1]; | const fir::ExtendedValue &value = args[1]; | ||||
const fir::ExtendedValue &length = args[2]; | const fir::ExtendedValue &length = args[2]; | ||||
const fir::ExtendedValue &status = args[3]; | const fir::ExtendedValue &status = args[3]; | ||||
const fir::ExtendedValue &errmsg = args[4]; | const fir::ExtendedValue &errmsg = args[4]; | ||||
if (!number) | if (!number) | ||||
fir::emitFatalError(loc, "expected NUMBER parameter"); | fir::emitFatalError(loc, "expected NUMBER parameter"); | ||||
if (isStaticallyPresent(value) || isStaticallyPresent(status) || | // If none of the optional parameters are present, do nothing. | ||||
isStaticallyPresent(errmsg)) { | if (!isStaticallyPresent(value) && !isStaticallyPresent(length) && | ||||
!isStaticallyPresent(status) && !isStaticallyPresent(errmsg)) | |||||
return; | |||||
mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType()); | mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType()); | ||||
mlir::Value valBox = | mlir::Value valBox = | ||||
isStaticallyPresent(value) | isStaticallyPresent(value) | ||||
? fir::getBase(value) | ? fir::getBase(value) | ||||
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult(); | : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult(); | ||||
mlir::Value lenBox = | |||||
isStaticallyPresent(length) | |||||
? fir::getBase(length) | |||||
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult(); | |||||
mlir::Value errBox = | mlir::Value errBox = | ||||
isStaticallyPresent(errmsg) | isStaticallyPresent(errmsg) | ||||
? fir::getBase(errmsg) | ? fir::getBase(errmsg) | ||||
: builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult(); | : builder.create<fir::AbsentOp>(loc, boxNoneTy).getResult(); | ||||
mlir::Value stat = | mlir::Value stat = fir::runtime::genGetCommandArgument( | ||||
fir::runtime::genArgumentValue(builder, loc, number, valBox, errBox); | builder, loc, number, valBox, lenBox, errBox); | ||||
if (isStaticallyPresent(status)) { | if (isStaticallyPresent(status)) { | ||||
mlir::Value statAddr = fir::getBase(status); | mlir::Value statAddr = fir::getBase(status); | ||||
mlir::Value statIsPresentAtRuntime = | mlir::Value statIsPresentAtRuntime = | ||||
builder.genIsNotNullAddr(loc, statAddr); | builder.genIsNotNullAddr(loc, statAddr); | ||||
builder.genIfThen(loc, statIsPresentAtRuntime) | builder.genIfThen(loc, statIsPresentAtRuntime) | ||||
.genThen( | .genThen([&]() { builder.createStoreWithConvert(loc, stat, statAddr); }) | ||||
[&]() { builder.createStoreWithConvert(loc, stat, statAddr); }) | |||||
.end(); | |||||
} | |||||
} | |||||
if (isStaticallyPresent(length)) { | |||||
mlir::Value lenAddr = fir::getBase(length); | |||||
mlir::Value lenIsPresentAtRuntime = builder.genIsNotNullAddr(loc, lenAddr); | |||||
builder.genIfThen(loc, lenIsPresentAtRuntime) | |||||
.genThen([&]() { | |||||
mlir::Value len = | |||||
fir::runtime::genArgumentLength(builder, loc, number); | |||||
builder.createStoreWithConvert(loc, len, lenAddr); | |||||
}) | |||||
.end(); | .end(); | ||||
} | } | ||||
} | } | ||||
// GET_ENVIRONMENT_VARIABLE | // GET_ENVIRONMENT_VARIABLE | ||||
void IntrinsicLibrary::genGetEnvironmentVariable( | void IntrinsicLibrary::genGetEnvironmentVariable( | ||||
llvm::ArrayRef<fir::ExtendedValue> args) { | llvm::ArrayRef<fir::ExtendedValue> args) { | ||||
assert(args.size() == 6); | assert(args.size() == 6); | ||||
▲ Show 20 Lines • Show All 1,699 Lines • Show Last 20 Lines |
STATUS is also optional, I think it also needs to have handleDynamicOptional so that the OPTIONAL POINTER/OPTIONAL ALLOCATABLE edge case are handled correctly (I think the current code might unconditionally dereference the descriptor in these case).