Files
Heejin Ahn c0ef9c53ec [WebAssembly] Use SubtargetFeature's Implies field (#206643)
This makes use of `SubtargetFeature`'s `Implies` field, which lets us
define feature dependencies:

https://github.com/llvm/llvm-project/blob/442c59c75ca384db53a6d6d81686b17ea4b397c3/llvm/include/llvm/Target/Target.td#L568-L571
and removes C++ code that specified feature dependencies.

These are the dependencies specified. EH dependencies are currently only
specified in clang options, and others are specified in
`WebAssemblySubtarget.cpp`.
- exception-handling implies multivalue and reference-types
- bulk-memory implifes bulk-memory-opt
- gc implies reference-types
- reference-types implies call-indirect-overlong

The features in `WebAssembly.td` were sorted in the alphabetical order,
but this changes it because implied features have to come before the
implying feature, e.g., multivalue and reference-types have to come
before exception-handling.

---

One semantic difference from the current code, is, when reference-types
implies call-indirect-overlong,
```console
llc -mattr=+reference-types,-call-indirect-overlong
```
this currently forces call-indirect-overlong to be true despite there is
`-call-indirect-overlong`, because

https://github.com/llvm/llvm-project/blob/442c59c75ca384db53a6d6d81686b17ea4b397c3/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp#L63-L67

But with the `Implies` field, disabling call-indirect-overlong disabled
both features, because TableGen thinks reference-types depends on
call-indirect-overlong, so without call-indirect-overlong,
reference-types can't be enabled. This is not exactly true with the
relationship of reference-types and call-indirect-overlong, but
generally makes sense for true dependencies, like exception-handling
implying (=depending on) multivalue and reference-types.

Also this wouldn't really affect the end users because these are `llc`
flags.
2026-07-09 00:04:52 -07:00

98 lines
3.4 KiB
C++

//===-- WebAssemblySubtarget.cpp - WebAssembly Subtarget Information ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the WebAssembly-specific subclass of
/// TargetSubtarget.
///
//===----------------------------------------------------------------------===//
#include "WebAssemblySubtarget.h"
#include "GISel/WebAssemblyCallLowering.h"
#include "GISel/WebAssemblyLegalizerInfo.h"
#include "GISel/WebAssemblyRegisterBankInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
#define DEBUG_TYPE "wasm-subtarget"
#define GET_SUBTARGETINFO_CTOR
#define GET_SUBTARGETINFO_TARGET_DESC
#include "WebAssemblyGenSubtargetInfo.inc"
WebAssemblySubtarget &
WebAssemblySubtarget::initializeSubtargetDependencies(StringRef CPU,
StringRef FS) {
// Determine default and user-specified characteristics
LLVM_DEBUG(llvm::dbgs() << "initializeSubtargetDependencies\n");
if (CPU.empty())
CPU = "generic";
ParseSubtargetFeatures(CPU, /*TuneCPU*/ CPU, FS);
// WASIP3 uses cooperative multithreading, which implies using libcall
// thread context.
if (TargetTriple.getOS() == Triple::WASIp3) {
HasCooperativeMultithreading = true;
HasLibcallThreadContext = true;
}
return *this;
}
WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT,
const std::string &CPU,
const std::string &FS,
const TargetMachine &TM)
: WebAssemblyGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
TLInfo(TM, *this) {
CallLoweringInfo.reset(new WebAssemblyCallLowering(*getTargetLowering()));
Legalizer.reset(new WebAssemblyLegalizerInfo(*this));
auto *RBI = new WebAssemblyRegisterBankInfo(*getRegisterInfo());
RegBankInfo.reset(RBI);
InstSelector.reset(createWebAssemblyInstructionSelector(
*static_cast<const WebAssemblyTargetMachine *>(&TM), *this, *RBI));
}
bool WebAssemblySubtarget::enableAtomicExpand() const {
// If atomics are disabled, atomic ops are lowered instead of expanded
return hasAtomics();
}
bool WebAssemblySubtarget::enableMachineScheduler() const {
// Disable the MachineScheduler for now. Even with ShouldTrackPressure set and
// enableMachineSchedDefaultSched overridden, it appears to have an overall
// negative effect for the kinds of register optimizations we're doing.
return false;
}
bool WebAssemblySubtarget::useAA() const { return true; }
const CallLowering *WebAssemblySubtarget::getCallLowering() const {
return CallLoweringInfo.get();
}
InstructionSelector *WebAssemblySubtarget::getInstructionSelector() const {
return InstSelector.get();
}
const LegalizerInfo *WebAssemblySubtarget::getLegalizerInfo() const {
return Legalizer.get();
}
const RegisterBankInfo *WebAssemblySubtarget::getRegBankInfo() const {
return RegBankInfo.get();
}