LLVM: lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

35#include

36using namespace llvm;

37

38#define DEBUG_TYPE "wasm"

39

40

41

42

43

45 "wasm-disable-explicit-locals", cl::Hidden,

46 cl::desc("WebAssembly: output implicit locals in"

47 " instruction output for test purposes only."),

49

51 "wasm-disable-fix-irreducible-control-flow-pass", cl::Hidden,

52 cl::desc("webassembly: disables the fix "

53 " irreducible control flow optimization pass"),

55

56

57

58

60 "enable-emscripten-cxx-exceptions",

61 cl::desc("WebAssembly Emscripten-style exception handling"),

63

65 "enable-emscripten-sjlj",

66 cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),

68

71 cl::desc("WebAssembly exception handling"));

72

74 "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));

75

76

77

78

79

80

82 "wasm-use-legacy-eh", cl::desc("WebAssembly exception handling (legacy)"),

84

125

126

127

128

129

136

141

143

144

145 if (WasmEnableEmEH && WasmEnableEH)

147 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");

148

149 if (WasmEnableEmSjLj && WasmEnableSjLj)

151 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");

152

153 if (WasmEnableEmEH && WasmEnableSjLj)

155 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");

156

158

159

162 }

163

164

167 report_fatal_error("-exception-model should be either 'none' or 'wasm'");

170 "-enable-emscripten-cxx-exceptions");

173 "-wasm-enable-eh only allowed with -exception-model=wasm");

176 "-wasm-enable-sjlj only allowed with -exception-model=wasm");

177 if ((!WasmEnableEH && !WasmEnableSjLj) &&

180 "-exception-model=wasm only allowed with at least one of "

181 "-wasm-enable-eh or -wasm-enable-sjlj");

182

183

184

185

186}

187

188

189

193 std::optionalCodeModel::Model CM, CodeGenOptLevel OL, bool JIT)

198 UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") {

199

200

201

202

203

204

205

208

209

210

214

217

218

219

220}

221

223

228

231 std::string FS) const {

232 auto &I = SubtargetMap[CPU + FS];

233 if (I) {

234 I = std::make_unique(TargetTriple, CPU, FS, *this);

235 }

236 return I.get();

237}

238

241 Attribute CPUAttr = F.getFnAttribute("target-cpu");

242 Attribute FSAttr = F.getFnAttribute("target-features");

243

244 std::string CPU =

246 std::string FS =

248

249

250

251

253

255}

256

257namespace {

258

259class CoalesceFeaturesAndStripAtomics final : public ModulePass {

260

261

262

263

264 static char ID;

266

267public:

270

271 bool runOnModule(Module &M) override {

273

274 std::string FeatureStr = getFeatureString(Features);

276 for (auto &F : M)

277 replaceFeatures(F, FeatureStr);

278

279 bool StrippedAtomics = false;

280 bool StrippedTLS = false;

281

282 if (!Features[WebAssembly::FeatureAtomics]) {

283 StrippedAtomics = stripAtomics(M);

284 StrippedTLS = stripThreadLocals(M);

285 } else if (!Features[WebAssembly::FeatureBulkMemory]) {

286 StrippedTLS |= stripThreadLocals(M);

287 }

288

289 if (StrippedAtomics && !StrippedTLS)

290 stripThreadLocals(M);

291 else if (StrippedTLS && !StrippedAtomics)

292 stripAtomics(M);

293

294 recordFeatures(M, Features, StrippedAtomics || StrippedTLS);

295

296

297 return true;

298 }

299

300private:

301 FeatureBitset coalesceFeatures(const Module &M) {

302

303

304

305

306 FeatureBitset Features;

307 bool AnyDefinedFuncs = false;

308 for (auto &F : M) {

309 if (F.isDeclaration())

310 continue;

311

313 AnyDefinedFuncs = true;

314 }

315

316

317

318 if (!AnyDefinedFuncs) {

319 Features =

320 WasmTM

323 ->getFeatureBits();

324 }

325

326 return Features;

327 }

328

329 static std::string getFeatureString(const FeatureBitset &Features) {

330 std::string Ret;

332 if (Features[KV.Value])

333 Ret += (StringRef("+") + KV.Key + ",").str();

334 else

335 Ret += (StringRef("-") + KV.Key + ",").str();

336 }

337 return Ret;

338 }

339

340 void replaceFeatures(Function &F, const std::string &Features) {

341 F.removeFnAttr("target-features");

342 F.removeFnAttr("target-cpu");

343 F.addFnAttr("target-features", Features);

344 }

345

346 bool stripAtomics(Module &M) {

347

348

349 bool Stripped = false;

350 for (auto &F : M) {

351 for (auto &B : F) {

352 for (auto &I : B) {

353 if (I.isAtomic()) {

354 Stripped = true;

355 goto done;

356 }

357 }

358 }

359 }

360

361 done:

362 if (!Stripped)

363 return false;

364

365 LowerAtomicPass Lowerer;

367 for (auto &F : M)

369

370 return true;

371 }

372

373 bool stripThreadLocals(Module &M) {

374 bool Stripped = false;

375 for (auto &GV : M.globals()) {

376 if (GV.isThreadLocal()) {

377

380 if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&

381 II->getArgOperand(0) == &GV) {

382 II->replaceAllUsesWith(&GV);

383 II->eraseFromParent();

384 }

385 }

386 }

387

388 Stripped = true;

389 GV.setThreadLocal(false);

390 }

391 }

392 return Stripped;

393 }

394

395 void recordFeatures(Module &M, const FeatureBitset &Features, bool Stripped) {

397 if (Features[KV.Value]) {

398

399 std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();

400 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,

402 }

403 }

404

405

406

407

408

409 if (Stripped) {

410 M.addModuleFlag(Module::ModFlagBehavior::Error, "wasm-feature-shared-mem",

412 }

413 }

414};

415char CoalesceFeaturesAndStripAtomics::ID = 0;

416

417

419public:

420 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)

421 : TargetPassConfig(TM, PM) {}

422

423 WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {

425 }

426

427 FunctionPass *createTargetRegisterAllocator(bool) override;

428

429 void addIRPasses() override;

430 void addISelPrepare() override;

431 bool addInstSelector() override;

432 void addOptimizedRegAlloc() override;

433 void addPostRegAlloc() override;

434 bool addGCPasses() override { return false; }

435 void addPreEmitPass() override;

436 bool addPreISel() override;

437

438

439 bool addRegAssignAndRewriteFast() override { return false; }

440

441

442 bool addRegAssignAndRewriteOptimized() override { return false; }

443};

444}

445

452

457

460 return new WebAssemblyPassConfig(*this, PM);

461}

462

463FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {

464 return nullptr;

465}

466

467

468

469

470

471

472void WebAssemblyPassConfig::addIRPasses() {

473

475

476

478

479

480

482

483

486

487

488

489

490

491

492

493 if (!WasmEnableEmEH && !WasmEnableEH) {

495

496

498 }

499

500

501

502

503

504 if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj)

506

507

509

511}

512

513void WebAssemblyPassConfig::addISelPrepare() {

514

515

517

518 addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));

519

520

522

524}

525

526bool WebAssemblyPassConfig::addInstSelector() {

528 addPass(

530

531

532

534

535

536

538

539

541

542

543

545

546 return false;

547}

548

549void WebAssemblyPassConfig::addOptimizedRegAlloc() {

550

551

552

553

554

555

556

560}

561

562void WebAssemblyPassConfig::addPostRegAlloc() {

563

564

565

566

567

577

578

579

581

583}

584

585void WebAssemblyPassConfig::addPreEmitPass() {

587

588

590

591

594

595

596

599

600

601

602

604

605

607

609

610

612 }

613

614

615

616

617

618

620

622

623

624

626 }

627

628

629

631

632

634

635

638

639

641

642

645

646

648

649

652

653

655}

656

657bool WebAssemblyPassConfig::addPreISel() {

660 return false;

661}

662

667

673

static Reloc::Model getEffectiveRelocModel()

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_EXTERNAL_VISIBILITY

Machine Check Debug Module

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

const GCNTargetMachine & getTM(const GCNSubtarget *STI)

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

Target-Independent Code Generator Pass Configuration Options pass.

This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG.

This file provides WebAssembly-specific target descriptions.

This file declares WebAssembly-specific per-machine-function information.

This file registers the WebAssembly target.

LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget()

Definition WebAssemblyTargetMachine.cpp:86

static void basicCheckForEHAndSjLj(TargetMachine *TM)

Definition WebAssemblyTargetMachine.cpp:142

static cl::opt< bool > WasmDisableExplicitLocals("wasm-disable-explicit-locals", cl::Hidden, cl::desc("WebAssembly: output implicit locals in" " instruction output for test purposes only."), cl::init(false))

static cl::opt< bool > WasmDisableFixIrreducibleControlFlowPass("wasm-disable-fix-irreducible-control-flow-pass", cl::Hidden, cl::desc("webassembly: disables the fix " " irreducible control flow optimization pass"), cl::init(false))

This file declares the WebAssembly-specific subclass of TargetMachine.

This file declares the WebAssembly-specific subclass of TargetLoweringObjectFile.

This file a TargetTransformInfoImplBase conforming object specific to the WebAssembly target machine.

This file contains the declaration of the WebAssembly-specific utility functions.

This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.

Functions, function parameters, and return types can have attributes to indicate how they should be t...

LLVM_ABI StringRef getValueAsString() const

Return the attribute's value as a string.

bool isValid() const

Return true if the attribute is any kind of attribute.

CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)

Lightweight error class with error context and mandatory checking.

Container class for subtarget features.

FunctionPass class - This class is used to implement most global optimizations.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &)

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

A Module instance is used to store all the information related to an LLVM module.

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...

Represents a range in source code.

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

Primary interface to the complete machine description for the target machine.

Triple TargetTriple

Triple string, CPU name, and target feature strings the TargetMachine instance is created with.

StringRef getTargetFeatureString() const

StringRef getTargetCPU() const

std::unique_ptr< const MCSubtargetInfo > STI

void setTargetFeatureString(StringRef FS)

void resetTargetOptions(const Function &F) const

Reset the target options based on the function's attributes.

unsigned UniqueSectionNames

unsigned FunctionSections

Emit functions into separate sections.

unsigned NoTrapAfterNoreturn

Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...

unsigned DataSections

Emit data into separate sections.

unsigned TrapUnreachable

Emit target-specific trap instruction for 'unreachable' IR instructions.

ExceptionHandling ExceptionModel

What exception model to use.

Target-Independent Code Generator Pass Configuration Options.

virtual void addPostRegAlloc()

This method may be implemented by targets that want to run passes after register allocation pass pipe...

virtual bool addInstSelector()

addInstSelector - This method should install an instruction selector pass, which converts from LLVM c...

virtual bool addPreISel()

Methods with trivial inline returns are convenient points in the common codegen pass pipeline where t...

virtual void addOptimizedRegAlloc()

addOptimizedRegAlloc - Add passes related to register allocation.

virtual void addPreEmitPass()

This pass may be implemented by targets that want to run passes immediately before machine code is em...

virtual void addIRPasses()

Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...

virtual void addISelPrepare()

Add common passes that perform LLVM IR to IR transforms in preparation for instruction selection.

TargetSubtargetInfo - Generic base class for all target subtargets.

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...

yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override

Allocate and return a default initialized instance of the YAML representation for the MachineFunction...

Definition WebAssemblyTargetMachine.cpp:664

bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override

Parse out the target's MachineFunctionInfo from the YAML reprsentation.

Definition WebAssemblyTargetMachine.cpp:674

WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)

Create an WebAssembly architecture model.

Definition WebAssemblyTargetMachine.cpp:190

TargetPassConfig * createPassConfig(PassManagerBase &PM) override

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...

Definition WebAssemblyTargetMachine.cpp:459

const WebAssemblySubtarget * getSubtargetImpl() const

Definition WebAssemblyTargetMachine.cpp:224

MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override

Create the target's instance of MachineFunctionInfo.

Definition WebAssemblyTargetMachine.cpp:446

~WebAssemblyTargetMachine() override

TargetTransformInfo getTargetTransformInfo(const Function &F) const override

Get a TargetTransformInfo implementation for the target.

Definition WebAssemblyTargetMachine.cpp:454

yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override

Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.

Definition WebAssemblyTargetMachine.cpp:668

PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

cl::opt< bool > WasmUseLegacyEH

cl::opt< bool > WasmEnableEH

cl::opt< bool > WasmEnableSjLj

cl::opt< bool > WasmEnableEmEH

cl::opt< bool > WasmEnableEmSjLj

initializer< Ty > init(const Ty &Val)

@ WASM_FEATURE_PREFIX_USED

@ WASM_FEATURE_PREFIX_DISALLOWED

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI ModulePass * createLowerGlobalDtorsLegacyPass()

void initializeOptimizeReturnedPass(PassRegistry &)

LLVM_ABI FunctionPass * createIndirectBrExpandPass()

void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)

FunctionPass * createWebAssemblyLowerRefTypesIntPtrConv()

FunctionPass * createWebAssemblyRegNumbering()

ModulePass * createWebAssemblyAddMissingPrototypes()

LLVM_ABI char & RegisterCoalescerID

RegisterCoalescer - This pass merges live ranges to eliminate copies.

FunctionPass * createWebAssemblyLateEHPrepare()

const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

void initializeWebAssemblyLateEHPreparePass(PassRegistry &)

@ None

No exception support.

@ Wasm

WebAssembly Exception Handling.

FunctionPass * createWebAssemblyFixBrTableDefaults()

void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &)

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

LLVM_ABI char & PatchableFunctionID

This pass implements the "patchable-function" attribute.

void initializeWebAssemblyExceptionInfoPass(PassRegistry &)

LLVM_ABI char & PostRASchedulerID

PostRAScheduler - This pass performs post register allocation scheduling.

LLVM_ABI char & RemoveLoadsIntoFakeUsesID

RemoveLoadsIntoFakeUses pass.

void initializeWebAssemblyRegNumberingPass(PassRegistry &)

void initializeWebAssemblyLowerRefTypesIntPtrConvPass(PassRegistry &)

void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &)

FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)

FunctionPass * createWebAssemblyReplacePhysRegs()

void initializeWebAssemblyRegColoringPass(PassRegistry &)

static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)

CodeModel::Model getEffectiveCodeModel(std::optional< CodeModel::Model > CM, CodeModel::Model Default)

Helper method for getting the code model, returning Default if CM does not have a value.

FunctionPass * createWebAssemblyMemIntrinsicResults()

LLVM_ABI char & ShrinkWrapID

ShrinkWrap pass. Look for the best place to insert save and restore.

LLVM_ABI char & MachineLateInstrsCleanupID

MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...

FunctionPass * createWebAssemblyDebugFixup()

LLVM_ABI FunctionPass * createLowerInvokePass()

Target & getTheWebAssemblyTarget32()

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &)

LLVM_ABI char & StackMapLivenessID

StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...

LLVM_ABI void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)

void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &)

FunctionPass * createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel)

This pass converts a legalized DAG into a WebAssembly-specific DAG, ready for instruction scheduling.

LLVM_ABI char & FuncletLayoutID

This pass lays out funclets contiguously.

void initializeWebAssemblyRegStackifyPass(PassRegistry &)

FunctionPass * createWebAssemblyCFGStackify()

FunctionPass * createWebAssemblyOptimizeLiveIntervals()

LLVM_ABI char & PostRAMachineSinkingID

This pass perform post-ra machine sink for COPY instructions.

CodeGenOptLevel

Code generation optimization level.

FunctionPass * createWebAssemblyOptimizeReturned()

FunctionPass * createWebAssemblyRefTypeMem2Local()

FunctionPass * createWebAssemblyCleanCodeAfterTrap()

void initializeWebAssemblyOptimizeLiveIntervalsPass(PassRegistry &)

FunctionPass * createWebAssemblySetP2AlignOperands()

ModulePass * createWebAssemblyLowerEmscriptenEHSjLj()

void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &)

FunctionPass * createWebAssemblyArgumentMove()

FunctionPass * createWebAssemblyExplicitLocals()

Target & getTheWebAssemblyTarget64()

void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &)

void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &)

void initializeWebAssemblyExplicitLocalsPass(PassRegistry &)

FunctionPass * createWebAssemblyFixIrreducibleControlFlow()

ModulePass * createWebAssemblyFixFunctionBitcasts()

FunctionPass * createWebAssemblyLowerBrUnless()

void initializeFixFunctionBitcastsPass(PassRegistry &)

FunctionPass * createWebAssemblyRegColoring()

void initializeWebAssemblyPeepholePass(PassRegistry &)

ModulePass * createWebAssemblyMCLowerPrePass()

void initializeWebAssemblyRefTypeMem2LocalPass(PassRegistry &)

LLVM_ABI char & MachineBlockPlacementID

MachineBlockPlacement - This pass places basic blocks based on branch probabilities.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()

AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...

FunctionPass * createWebAssemblyCFGSort()

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

void initializeWebAssemblyCFGSortPass(PassRegistry &)

void initializeWebAssemblyFixBrTableDefaultsPass(PassRegistry &)

FunctionPass * createWebAssemblyNullifyDebugValueLists()

void initializeWebAssemblyAsmPrinterPass(PassRegistry &)

void initializeWebAssemblyCFGStackifyPass(PassRegistry &)

void initializeWebAssemblySetP2AlignOperandsPass(PassRegistry &)

void initializeWebAssemblyDebugFixupPass(PassRegistry &)

LLVM_ABI char & MachineCopyPropagationID

MachineCopyPropagation - This pass performs copy propagation on machine instructions.

void initializeWebAssemblyArgumentMovePass(PassRegistry &)

LLVM_ABI FunctionPass * createUnreachableBlockEliminationPass()

createUnreachableBlockEliminationPass - The LLVM code generator does not work well with unreachable b...

FunctionPass * createWebAssemblyPeephole()

void initializeWebAssemblyReplacePhysRegsPass(PassRegistry &)

MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...

static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)

Factory function: default behavior is to call new using the supplied allocator.

RegisterTargetMachine - Helper template for registering a target machine implementation,...

Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.