clang: lib/Driver/ToolChains/Flang.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

12

15#include "llvm/Frontend/Debug/Options.h"

16#include "llvm/Support/FileSystem.h"

17#include "llvm/Support/Path.h"

18#include "llvm/TargetParser/Host.h"

19#include "llvm/TargetParser/RISCVISAInfo.h"

20#include "llvm/TargetParser/RISCVTargetParser.h"

21

22#include

23

26using namespace clang;

28

29

31 ArgStringList &CmdArgs) {

32 CmdArgs.push_back("-x");

33

35}

36

37void Flang::addFortranDialectOptions(const ArgList &Args,

38 ArgStringList &CmdArgs) const {

39 Args.addAllArgs(CmdArgs, {options::OPT_ffixed_form,

40 options::OPT_ffree_form,

41 options::OPT_ffixed_line_length_EQ,

42 options::OPT_fopenacc,

43 options::OPT_finput_charset_EQ,

44 options::OPT_fimplicit_none,

45 options::OPT_fno_implicit_none,

46 options::OPT_fbackslash,

47 options::OPT_fno_backslash,

48 options::OPT_flogical_abbreviations,

49 options::OPT_fno_logical_abbreviations,

50 options::OPT_fxor_operator,

51 options::OPT_fno_xor_operator,

52 options::OPT_falternative_parameter_statement,

53 options::OPT_fdefault_real_8,

54 options::OPT_fdefault_integer_8,

55 options::OPT_fdefault_double_8,

56 options::OPT_flarge_sizes,

57 options::OPT_fno_automatic,

58 options::OPT_fhermetic_module_files,

59 options::OPT_frealloc_lhs,

60 options::OPT_fno_realloc_lhs,

61 options::OPT_fsave_main_program});

62}

63

64void Flang::addPreprocessingOptions(const ArgList &Args,

65 ArgStringList &CmdArgs) const {

66 Args.addAllArgs(CmdArgs,

67 {options::OPT_P, options::OPT_D, options::OPT_U,

68 options::OPT_I, options::OPT_cpp, options::OPT_nocpp});

69}

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

89 const Arg *LoopVersioningArg = Args.getLastArg(

90 options::OPT_Ofast, options::OPT_O, options::OPT_O4,

91 options::OPT_floop_versioning, options::OPT_fno_loop_versioning);

92 if (!LoopVersioningArg)

93 return false;

94

95 if (LoopVersioningArg->getOption().matches(options::OPT_fno_loop_versioning))

96 return false;

97

98 if (LoopVersioningArg->getOption().matches(options::OPT_floop_versioning))

99 return true;

100

101 if (LoopVersioningArg->getOption().matches(options::OPT_Ofast) ||

102 LoopVersioningArg->getOption().matches(options::OPT_O4))

103 return true;

104

105 if (LoopVersioningArg->getOption().matches(options::OPT_O)) {

106 StringRef S(LoopVersioningArg->getValue());

107 unsigned OptLevel = 0;

108

109

110 if (S.getAsInteger(10, OptLevel))

111 return false;

112

113 return OptLevel > 2;

114 }

115

116 llvm_unreachable("We should not end up here");

117 return false;

118}

119

120void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {

121 Args.addAllArgs(CmdArgs,

122 {options::OPT_module_dir, options::OPT_fdebug_module_writer,

123 options::OPT_fintrinsic_modules_path, options::OPT_pedantic,

124 options::OPT_std_EQ, options::OPT_W_Joined,

125 options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,

126 options::OPT_funderscoring, options::OPT_fno_underscoring,

127 options::OPT_funsigned, options::OPT_fno_unsigned});

128

129 llvm::codegenoptions::DebugInfoKind DebugInfoKind;

130 if (Args.hasArg(options::OPT_gN_Group)) {

131 Arg *gNArg = Args.getLastArg(options::OPT_gN_Group);

133 } else if (Args.hasArg(options::OPT_g_Flag)) {

134 DebugInfoKind = llvm::codegenoptions::FullDebugInfo;

135 } else {

136 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;

137 }

139}

140

141void Flang::addCodegenOptions(const ArgList &Args,

142 ArgStringList &CmdArgs) const {

143 Arg *stackArrays =

144 Args.getLastArg(options::OPT_Ofast, options::OPT_fstack_arrays,

145 options::OPT_fno_stack_arrays);

146 if (stackArrays &&

147 !stackArrays->getOption().matches(options::OPT_fno_stack_arrays))

148 CmdArgs.push_back("-fstack-arrays");

149

151 CmdArgs.push_back("-fversion-loops-for-stride");

152

153 Args.addAllArgs(CmdArgs,

154 {options::OPT_flang_experimental_hlfir,

155 options::OPT_flang_deprecated_no_hlfir,

156 options::OPT_fno_ppc_native_vec_elem_order,

157 options::OPT_fppc_native_vec_elem_order,

158 options::OPT_finit_global_zero,

159 options::OPT_fno_init_global_zero, options::OPT_ftime_report,

160 options::OPT_ftime_report_EQ, options::OPT_funroll_loops,

161 options::OPT_fno_unroll_loops});

162}

163

164void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {

165

166

167 llvm::Reloc::Model RelocationModel;

168 unsigned PICLevel;

169 bool IsPIE;

170 std::tie(RelocationModel, PICLevel, IsPIE) =

172

174 CmdArgs.push_back("-mrelocation-model");

175 CmdArgs.push_back(RMName);

176 }

177 if (PICLevel > 0) {

178 CmdArgs.push_back("-pic-level");

179 CmdArgs.push_back(PICLevel == 1 ? "1" : "2");

180 if (IsPIE)

181 CmdArgs.push_back("-pic-is-pie");

182 }

183}

184

185void Flang::AddAArch64TargetArgs(const ArgList &Args,

186 ArgStringList &CmdArgs) const {

187

188 if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {

189 StringRef Val = A->getValue();

191 if (Val == "128" || Val == "256" || Val == "512" || Val == "1024" ||

192 Val == "2048" || Val == "128+" || Val == "256+" || Val == "512+" ||

193 Val == "1024+" || Val == "2048+") {

194 unsigned Bits = 0;

195 if (!Val.consume_back("+")) {

196 [[maybe_unused]] bool Invalid = Val.getAsInteger(10, Bits);

197 assert(Invalid && "Failed to parse value");

198 CmdArgs.push_back(

199 Args.MakeArgString("-mvscale-max=" + llvm::Twine(Bits / 128)));

200 }

201

202 [[maybe_unused]] bool Invalid = Val.getAsInteger(10, Bits);

203 assert(Invalid && "Failed to parse value");

204 CmdArgs.push_back(

205 Args.MakeArgString("-mvscale-min=" + llvm::Twine(Bits / 128)));

206

207 } else if (Val != "scalable")

208

209 D.Diag(diag::err_drv_unsupported_option_argument)

210 << A->getSpelling() << Val;

211 }

212}

213

214void Flang::AddLoongArch64TargetArgs(const ArgList &Args,

215 ArgStringList &CmdArgs) const {

217

218 if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {

219 StringRef V = A->getValue();

220 if (V != "lp64d") {

221 D.Diag(diag::err_drv_argument_not_allowed_with) << "-mabi" << V;

222 }

223 }

224

225 if (const Arg *A = Args.getLastArg(options::OPT_mannotate_tablejump,

226 options::OPT_mno_annotate_tablejump)) {

227 if (A->getOption().matches(options::OPT_mannotate_tablejump)) {

228 CmdArgs.push_back("-mllvm");

229 CmdArgs.push_back("-loongarch-annotate-tablejump");

230 }

231 }

232}

233

234void Flang::AddPPCTargetArgs(const ArgList &Args,

235 ArgStringList &CmdArgs) const {

237 bool VecExtabi = false;

238

239 if (const Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {

240 StringRef V = A->getValue();

241 if (V == "vec-extabi")

242 VecExtabi = true;

243 else if (V == "vec-default")

244 VecExtabi = false;

245 else

246 D.Diag(diag::err_drv_unsupported_option_argument)

247 << A->getSpelling() << V;

248 }

249

251 if (VecExtabi) {

252 if (T.isOSAIX()) {

253 D.Diag(diag::err_drv_unsupported_opt_for_target)

254 << "-mabi=vec-extabi" << T.str();

255 }

256 CmdArgs.push_back("-mabi=vec-extabi");

257 }

258}

259

260void Flang::AddRISCVTargetArgs(const ArgList &Args,

261 ArgStringList &CmdArgs) const {

263

264 if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {

265 StringRef Val = A->getValue();

267

268

269 unsigned MinVLen = 0;

271 auto ISAInfo = llvm::RISCVISAInfo::parseArchString(

272 Arch, true);

273

274 if (!errorToBool(ISAInfo.takeError()))

275 MinVLen = (*ISAInfo)->getMinVLen();

276

277

278

279 unsigned Bits = 0;

280 if (Val == "zvl" && MinVLen >= llvm::RISCV::RVVBitsPerBlock) {

281 Bits = MinVLen;

282 } else if (!Val.getAsInteger(10, Bits)) {

283

284

285 if (Bits < MinVLen || Bits < llvm::RISCV::RVVBitsPerBlock ||

286 Bits > 65536 || !llvm::isPowerOf2_32(Bits))

287 Bits = 0;

288 }

289

290

291 if (Bits != 0) {

292 unsigned VScaleMin = Bits / llvm::RISCV::RVVBitsPerBlock;

293 CmdArgs.push_back(

294 Args.MakeArgString("-mvscale-max=" + llvm::Twine(VScaleMin)));

295 CmdArgs.push_back(

296 Args.MakeArgString("-mvscale-min=" + llvm::Twine(VScaleMin)));

297 } else if (Val != "scalable") {

298

299 D.Diag(diag::err_drv_unsupported_option_argument)

300 << A->getSpelling() << Val;

301 }

302 }

303}

304

305void Flang::AddX86_64TargetArgs(const ArgList &Args,

306 ArgStringList &CmdArgs) const {

307 if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) {

308 StringRef Value = A->getValue();

309 if (Value == "intel" || Value == "att") {

310 CmdArgs.push_back(Args.MakeArgString("-mllvm"));

311 CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value));

312 } else {

314 << A->getSpelling() << Value;

315 }

316 }

317}

318

320 ArgStringList &CmdArgs) {

321

322 unsigned ver = 0;

324 ver = vt.getMajor() * 10000000 + vt.getMinor().value_or(0) * 100000 +

325 vt.getSubminor().value_or(0);

326 CmdArgs.push_back(Args.MakeArgString("-D_MSC_VER=" + Twine(ver / 100000)));

327 CmdArgs.push_back(Args.MakeArgString("-D_MSC_FULL_VER=" + Twine(ver)));

328 CmdArgs.push_back(Args.MakeArgString("-D_WIN32"));

329

330 const llvm::Triple &triple = TC.getTriple();

331 if (triple.isAArch64()) {

332 CmdArgs.push_back("-D_M_ARM64=1");

333 } else if (triple.isX86() && triple.isArch32Bit()) {

334 CmdArgs.push_back("-D_M_IX86=600");

335 } else if (triple.isX86() && triple.isArch64Bit()) {

336 CmdArgs.push_back("-D_M_X64=100");

337 } else {

338 llvm_unreachable(

339 "Flang on Windows only supports X86_32, X86_64 and AArch64");

340 }

341}

342

344 ArgStringList &CmdArgs) {

345 assert(TC.getTriple().isKnownWindowsMSVCEnvironment() &&

346 "can only add VS runtime library on Windows!");

347

348 if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {

349 CmdArgs.push_back(Args.MakeArgString(

351 }

352 unsigned RTOptionID = options::OPT__SLASH_MT;

353 if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {

354 RTOptionID = llvm::StringSwitch(rtl->getValue())

355 .Case("static", options::OPT__SLASH_MT)

356 .Case("static_dbg", options::OPT__SLASH_MTd)

357 .Case("dll", options::OPT__SLASH_MD)

358 .Case("dll_dbg", options::OPT__SLASH_MDd)

359 .Default(options::OPT__SLASH_MT);

360 }

361 switch (RTOptionID) {

362 case options::OPT__SLASH_MT:

363 CmdArgs.push_back("-D_MT");

364 CmdArgs.push_back("--dependent-lib=libcmt");

365 CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib");

366 CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib");

367 break;

368 case options::OPT__SLASH_MTd:

369 CmdArgs.push_back("-D_MT");

370 CmdArgs.push_back("-D_DEBUG");

371 CmdArgs.push_back("--dependent-lib=libcmtd");

372 CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib");

373 CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib");

374 break;

375 case options::OPT__SLASH_MD:

376 CmdArgs.push_back("-D_MT");

377 CmdArgs.push_back("-D_DLL");

378 CmdArgs.push_back("--dependent-lib=msvcrt");

379 CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib");

380 CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib");

381 break;

382 case options::OPT__SLASH_MDd:

383 CmdArgs.push_back("-D_MT");

384 CmdArgs.push_back("-D_DEBUG");

385 CmdArgs.push_back("-D_DLL");

386 CmdArgs.push_back("--dependent-lib=msvcrtd");

387 CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib");

388 CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib");

389 break;

390 }

391}

392

393void Flang::AddAMDGPUTargetArgs(const ArgList &Args,

394 ArgStringList &CmdArgs) const {

395 if (Arg *A = Args.getLastArg(options::OPT_mcode_object_version_EQ)) {

396 StringRef Val = A->getValue();

397 CmdArgs.push_back(Args.MakeArgString("-mcode-object-version=" + Val));

398 }

399

402}

403

404void Flang::addTargetOptions(const ArgList &Args,

405 ArgStringList &CmdArgs) const {

409

410 std::string CPU = getCPUName(D, Args, Triple);

411 if (!CPU.empty()) {

412 CmdArgs.push_back("-target-cpu");

413 CmdArgs.push_back(Args.MakeArgString(CPU));

414 }

415

417

418

420 default:

421 break;

422 case llvm::Triple::aarch64:

424 AddAArch64TargetArgs(Args, CmdArgs);

425 break;

426

427 case llvm::Triple::r600:

428 case llvm::Triple::amdgcn:

430 AddAMDGPUTargetArgs(Args, CmdArgs);

431 break;

432 case llvm::Triple::riscv64:

434 AddRISCVTargetArgs(Args, CmdArgs);

435 break;

436 case llvm::Triple::x86_64:

438 AddX86_64TargetArgs(Args, CmdArgs);

439 break;

440 case llvm::Triple::ppc:

441 case llvm::Triple::ppc64:

442 case llvm::Triple::ppc64le:

443 AddPPCTargetArgs(Args, CmdArgs);

444 break;

445 case llvm::Triple::loongarch64:

447 AddLoongArch64TargetArgs(Args, CmdArgs);

448 break;

449 }

450

451 if (Arg *A = Args.getLastArg(options::OPT_fveclib)) {

452 StringRef Name = A->getValue();

453 if (Name == "SVML") {

454 if (Triple.getArch() != llvm::Triple::x86 &&

455 Triple.getArch() != llvm::Triple::x86_64)

456 D.Diag(diag::err_drv_unsupported_opt_for_target)

457 << Name << Triple.getArchName();

458 } else if (Name == "LIBMVEC-X86") {

459 if (Triple.getArch() != llvm::Triple::x86 &&

460 Triple.getArch() != llvm::Triple::x86_64)

461 D.Diag(diag::err_drv_unsupported_opt_for_target)

462 << Name << Triple.getArchName();

463 } else if (Name == "SLEEF" || Name == "ArmPL") {

464 if (Triple.getArch() != llvm::Triple::aarch64 &&

465 Triple.getArch() != llvm::Triple::aarch64_be)

466 D.Diag(diag::err_drv_unsupported_opt_for_target)

467 << Name << Triple.getArchName();

468 }

469

470 if (Triple.isOSDarwin()) {

471

472

473 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {

474 if (A->getValue() == StringRef{"Accelerate"}) {

475 CmdArgs.push_back("-framework");

476 CmdArgs.push_back("Accelerate");

477 }

478 }

479 }

480 A->render(Args, CmdArgs);

481 }

482

483 if (Triple.isKnownWindowsMSVCEnvironment()) {

486 }

487

488

489 if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {

490 CmdArgs.push_back("-tune-cpu");

491 if (A->getValue() == StringRef{"native"})

492 CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));

493 else

494 CmdArgs.push_back(A->getValue());

495 }

496}

497

499 const JobAction &JA, const ArgList &Args,

500 ArgStringList &CmdArgs) const {

504

505

506

507

508

509

510

511

512

513 for (size_t i = 1; i < Inputs.size(); ++i) {

514 if (Inputs[i].getType() == types::TY_Nothing) {

515

516 } else if (IsHostOffloadingAction) {

517 CmdArgs.push_back(

518 Args.MakeArgString("-fembed-offload-object=" +

519 getToolChain().getInputFilename(Inputs[i])));

520 } else if (IsOpenMPDevice) {

521 if (Inputs[i].getFilename()) {

522 CmdArgs.push_back("-fopenmp-host-ir-file-path");

523 CmdArgs.push_back(Args.MakeArgString(Inputs[i].getFilename()));

524 } else {

525 llvm_unreachable("missing openmp host-ir file for device offloading");

526 }

527 } else {

528 llvm_unreachable(

529 "unexpectedly given multiple inputs or given unknown input");

530 }

531 }

532

533 if (IsOpenMPDevice) {

534

535

536 CmdArgs.push_back("-fopenmp-is-target-device");

537

538

539 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_target_debug_EQ);

540 if (Args.hasFlag(options::OPT_fopenmp_target_debug,

541 options::OPT_fno_openmp_target_debug, false))

542 CmdArgs.push_back("-fopenmp-target-debug");

543

544

545

546 if (Args.hasFlag(options::OPT_fopenmp_assume_teams_oversubscription,

547 options::OPT_fno_openmp_assume_teams_oversubscription,

548 false))

549 CmdArgs.push_back("-fopenmp-assume-teams-oversubscription");

550 if (Args.hasFlag(options::OPT_fopenmp_assume_threads_oversubscription,

551 options::OPT_fno_openmp_assume_threads_oversubscription,

552 false))

553 CmdArgs.push_back("-fopenmp-assume-threads-oversubscription");

554 if (Args.hasArg(options::OPT_fopenmp_assume_no_thread_state))

555 CmdArgs.push_back("-fopenmp-assume-no-thread-state");

556 if (Args.hasArg(options::OPT_fopenmp_assume_no_nested_parallelism))

557 CmdArgs.push_back("-fopenmp-assume-no-nested-parallelism");

558 if (Args.hasArg(options::OPT_nogpulib))

559 CmdArgs.push_back("-nogpulib");

560 }

561

563}

564

566 ArgStringList &CmdArgs) {

567 StringRef FPContract;

568 bool HonorINFs = true;

569 bool HonorNaNs = true;

570 bool ApproxFunc = false;

571 bool SignedZeros = true;

572 bool AssociativeMath = false;

573 bool ReciprocalMath = false;

574

575 if (const Arg *A = Args.getLastArg(options::OPT_ffp_contract)) {

576 const StringRef Val = A->getValue();

577 if (Val == "fast" || Val == "off") {

578 FPContract = Val;

579 } else if (Val == "on") {

580

581

582 D.Diag(diag::warn_drv_unsupported_option_for_flang)

583 << Val << A->getOption().getName() << "off";

584 FPContract = "off";

585 } else

586

587

588 D.Diag(diag::err_drv_unsupported_option_argument)

589 << A->getSpelling() << Val;

590 }

591

592 for (const Arg *A : Args) {

593 auto optId = A->getOption().getID();

594 switch (optId) {

595

596 default:

597 continue;

598

599 case options::OPT_fhonor_infinities:

600 HonorINFs = true;

601 break;

602 case options::OPT_fno_honor_infinities:

603 HonorINFs = false;

604 break;

605 case options::OPT_fhonor_nans:

606 HonorNaNs = true;

607 break;

608 case options::OPT_fno_honor_nans:

609 HonorNaNs = false;

610 break;

611 case options::OPT_fapprox_func:

612 ApproxFunc = true;

613 break;

614 case options::OPT_fno_approx_func:

615 ApproxFunc = false;

616 break;

617 case options::OPT_fsigned_zeros:

618 SignedZeros = true;

619 break;

620 case options::OPT_fno_signed_zeros:

621 SignedZeros = false;

622 break;

623 case options::OPT_fassociative_math:

624 AssociativeMath = true;

625 break;

626 case options::OPT_fno_associative_math:

627 AssociativeMath = false;

628 break;

629 case options::OPT_freciprocal_math:

630 ReciprocalMath = true;

631 break;

632 case options::OPT_fno_reciprocal_math:

633 ReciprocalMath = false;

634 break;

635 case options::OPT_Ofast:

636 [[fallthrough]];

637 case options::OPT_ffast_math:

638 HonorINFs = false;

639 HonorNaNs = false;

640 AssociativeMath = true;

641 ReciprocalMath = true;

642 ApproxFunc = true;

643 SignedZeros = false;

644 FPContract = "fast";

645 break;

646 case options::OPT_fno_fast_math:

647 HonorINFs = true;

648 HonorNaNs = true;

649 AssociativeMath = false;

650 ReciprocalMath = false;

651 ApproxFunc = false;

652 SignedZeros = true;

653

654

655

656 if (FPContract == "fast")

657 FPContract = "";

658 break;

659 }

660

661

662 A->claim();

663 }

664

665 if (!HonorINFs && !HonorNaNs && AssociativeMath && ReciprocalMath &&

666 ApproxFunc && !SignedZeros &&

667 (FPContract == "fast" || FPContract.empty())) {

668 CmdArgs.push_back("-ffast-math");

669 return;

670 }

671

672 if (!FPContract.empty())

673 CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + FPContract));

674

675 if (!HonorINFs)

676 CmdArgs.push_back("-menable-no-infs");

677

678 if (!HonorNaNs)

679 CmdArgs.push_back("-menable-no-nans");

680

681 if (ApproxFunc)

682 CmdArgs.push_back("-fapprox-func");

683

684 if (!SignedZeros)

685 CmdArgs.push_back("-fno-signed-zeros");

686

687 if (AssociativeMath && !SignedZeros)

688 CmdArgs.push_back("-mreassociate");

689

690 if (ReciprocalMath)

691 CmdArgs.push_back("-freciprocal-math");

692}

693

696 StringRef Format = "yaml";

697 if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))

698 Format = A->getValue();

699

700 CmdArgs.push_back("-opt-record-file");

701

702 const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);

703 if (A) {

704 CmdArgs.push_back(A->getValue());

705 } else {

707

708 if (Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) {

709 if (Arg *FinalOutput = Args.getLastArg(options::OPT_o))

710 F = FinalOutput->getValue();

711 }

712

713 if (F.empty()) {

714

715 F = llvm::sys::path::stem(Input.getBaseInput());

716 }

717

719 Extension += "opt.";

720 Extension += Format;

721

722 llvm::sys::path::replace_extension(F, Extension);

723 CmdArgs.push_back(Args.MakeArgString(F));

724 }

725

726 if (const Arg *A =

727 Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {

728 CmdArgs.push_back("-opt-record-passes");

729 CmdArgs.push_back(A->getValue());

730 }

731

732 if (!Format.empty()) {

733 CmdArgs.push_back("-opt-record-format");

734 CmdArgs.push_back(Format.data());

735 }

736}

737

740 const ArgList &Args, const char *LinkingOutput) const {

743 const std::string &TripleStr = Triple.getTriple();

744

746 ArgStringList CmdArgs;

748

749

750 CmdArgs.push_back("-fc1");

751

752

753 CmdArgs.push_back("-triple");

754 CmdArgs.push_back(Args.MakeArgString(TripleStr));

755

756 if (isa(JA)) {

757 CmdArgs.push_back("-E");

758 if (Args.getLastArg(options::OPT_dM)) {

759 CmdArgs.push_back("-dM");

760 }

761 } else if (isa(JA) || isa(JA)) {

762 if (JA.getType() == types::TY_Nothing) {

763 CmdArgs.push_back("-fsyntax-only");

764 } else if (JA.getType() == types::TY_AST) {

765 CmdArgs.push_back("-emit-ast");

766 } else if (JA.getType() == types::TY_LLVM_IR ||

767 JA.getType() == types::TY_LTO_IR) {

768 CmdArgs.push_back("-emit-llvm");

769 } else if (JA.getType() == types::TY_LLVM_BC ||

770 JA.getType() == types::TY_LTO_BC) {

771 CmdArgs.push_back("-emit-llvm-bc");

772 } else if (JA.getType() == types::TY_PP_Asm) {

773 CmdArgs.push_back("-S");

774 } else {

775 assert(false && "Unexpected output type!");

776 }

777 } else if (isa(JA)) {

778 CmdArgs.push_back("-emit-obj");

779 } else if (isa(JA)) {

780

781

782 } else {

783 assert(false && "Unexpected action class for Flang tool.");

784 }

785

786 const InputInfo &Input = Inputs[0];

788

789

790

792 addPreprocessingOptions(Args, CmdArgs);

793

794 addFortranDialectOptions(Args, CmdArgs);

795

796

797

798

799 if (InputType == types::TY_PP_Fortran &&

800 !Args.getLastArg(options::OPT_ffixed_form, options::OPT_ffree_form))

801 CmdArgs.push_back("-ffixed-form");

802

804

805

806 LTOKind LTOMode = D.getLTOMode();

807 assert(LTOMode != LTOK_Unknown && "Unknown LTO mode.");

809 CmdArgs.push_back("-flto=full");

813 "the option '-flto=thin' is a work in progress"));

814 CmdArgs.push_back("-flto=thin");

815 }

816

817

818 addPicOptions(Args, CmdArgs);

819

820

822

823

824 addTargetOptions(Args, CmdArgs);

825

826 llvm::Reloc::Model RelocationModel =

828

829 addMCModel(D, Args, Triple, RelocationModel, CmdArgs);

830

831

832 addCodegenOptions(Args, CmdArgs);

833

834

835 Args.AddAllArgs(CmdArgs, options::OPT_R_Group);

836

837

840

841

842 addOtherOptions(Args, CmdArgs);

843

844

845

846 Args.AddLastArg(CmdArgs, options::OPT_w);

847

848

849

850 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,

851 options::OPT_fno_openmp, false) &&

854 switch (D.getOpenMPRuntime(Args)) {

857

858 CmdArgs.push_back("-fopenmp");

859 Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);

860

861 if (Args.hasArg(options::OPT_fopenmp_force_usm))

862 CmdArgs.push_back("-fopenmp-force-usm");

863

864

865 D.Diag(diag::warn_openmp_experimental);

866

867

868 break;

869 default:

870

871

872

873

874

875

876 const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);

877 D.Diag(diag::warn_drv_unsupported_openmp_library)

878 << A->getSpelling() << A->getValue();

879 break;

880 }

881 }

882

883

884 CmdArgs.push_back("-resource-dir");

885 CmdArgs.push_back(D.ResourceDir.c_str());

886

887

888 addOffloadOptions(C, Inputs, JA, Args, CmdArgs);

889

890

891 Args.AddAllArgValues(CmdArgs, options::OPT_Xflang);

892

895

896 const char *FPKeepKindStr = nullptr;

897 switch (FPKeepKind) {

899 FPKeepKindStr = "-mframe-pointer=none";

900 break;

902 FPKeepKindStr = "-mframe-pointer=reserved";

903 break;

905 FPKeepKindStr = "-mframe-pointer=non-leaf";

906 break;

908 FPKeepKindStr = "-mframe-pointer=all";

909 break;

910 }

911 assert(FPKeepKindStr && "unknown FramePointerKind");

912 CmdArgs.push_back(FPKeepKindStr);

913

914

915

916 for (const Arg *A : Args.filtered(options::OPT_mllvm)) {

917 A->claim();

918 A->render(Args, CmdArgs);

919 }

920

921 for (const Arg *A : Args.filtered(options::OPT_mmlir)) {

922 A->claim();

923 A->render(Args, CmdArgs);

924 }

925

926

927 for (const Arg *A : Args.filtered(options::OPT_flang_ignored_w_Group)) {

928 A->claim();

929 D.Diag(diag::warn_drv_unsupported_diag_option_for_flang)

930 << A->getOption().getName();

931 }

932

933

934 if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) {

935 if (A->getOption().matches(options::OPT_O4)) {

936 CmdArgs.push_back("-O3");

937 D.Diag(diag::warn_O4_is_O3);

938 } else if (A->getOption().matches(options::OPT_Ofast)) {

939 CmdArgs.push_back("-O3");

940 } else {

941 A->render(Args, CmdArgs);

942 }

943 }

944

946

947 assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");

949 CmdArgs.push_back("-o");

951 }

952

953 if (Args.getLastArg(options::OPT_save_temps_EQ))

954 Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);

955

957

958 bool FRecordCmdLine = false;

959 bool GRecordCmdLine = false;

962 if (FRecordCmdLine) {

963 CmdArgs.push_back("-record-command-line");

964 CmdArgs.push_back(CmdLine);

965 }

967 CmdArgs.push_back("-dwarf-debug-flags");

968 CmdArgs.push_back(CmdLine);

969 }

970 }

971

972

973

976 FrontendInputs = {};

977

978 for (const InputInfo &Input : FrontendInputs) {

981 else

982 Input.getInputArg().renderAsInput(Args, CmdArgs);

983 }

984

985 const char *Exec = Args.MakeArgString(D.GetProgramPath("flang", TC));

986 C.addCommand(std::make_unique(JA, *this,

988 Exec, CmdArgs, Inputs, Output));

989}

990

992

static void addDashXForInput(const ArgList &Args, const InputInfo &Input, ArgStringList &CmdArgs)

Add -x lang to CmdArgs for Input.

static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple, const InputInfo &Input, const InputInfo &Output, const JobAction &JA)

clang::CodeGenOptions::FramePointerKind getFramePointerKind(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)

static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs)

static void addVSDefines(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs)

static bool shouldLoopVersion(const ArgList &Args)

@C shouldLoopVersion

static void addDashXForInput(const ArgList &Args, const InputInfo &Input, ArgStringList &CmdArgs)

Add -x lang to CmdArgs for Input.

static void addFloatingPointOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs)

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

types::ID getType() const

bool isHostOffloading(unsigned int OKind) const

Check if this action have any offload kinds.

bool isDeviceOffloading(OffloadKind OKind) const

Compilation - A set of tasks to perform for a single driver invocation.

Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...

DiagnosticBuilder Diag(unsigned DiagID) const

@ OMPRT_IOMP5

The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.

@ OMPRT_OMP

The LLVM OpenMP runtime.

InputInfo - Wrapper for information about an input source.

const char * getBaseInput() const

const llvm::opt::Arg & getInputArg() const

const char * getFilename() const

types::ID getType() const

ID getPreprocessedType(ID Id)

getPreprocessedType - Get the ID of the type for this input when it has been preprocessed,...

const char * getTypeName(ID Id)

getTypeName - Return the name of the type for Id.

LTOKind

Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.

bool willEmitRemarks(const llvm::opt::ArgList &Args)

The JSON file list parser is used to communicate input to InstallAPI.

const FunctionProtoType * T

static constexpr ResponseFileSupport AtFileUTF8()