This is an archive of the discontinued LLVM Phabricator instance.

[lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm*
ClosedPublic

Authored by mgorny on Aug 30 2021, 12:29 PM.

Details

Summary

gdbserver does not expose combined ymm* registers but rather XSAVE-style
split xmm* and ymm*h portions. Extend value_regs to support combining
multiple registers and use it to create user-friendly ymm* registers
that are combined from split xmm* and ymm*h portions.

Diff Detail

Event Timeline

mgorny created this revision.Aug 30 2021, 12:29 PM
mgorny requested review of this revision.Aug 30 2021, 12:29 PM
mgorny updated this revision to Diff 380058.Oct 15 2021, 10:48 AM
mgorny retitled this revision from [lldb] [Process/gdb-remote] Support combining xmm* and ymm*h regs into ymm* to [lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm*.

Rebase to use the new ABIX86::AugmentRegisterInfo() API.

I like the solution with multiple value_regs.

However, I am wondering if instead of the various piecemeal maps we couldn't just have one uber-map to rule them all. I'm imagining something like

enum (class?) RegKind { GPR, FPR, XMM, ...};
struct RegData {
  size_t index;
  StringRef name;
  SmallVector<StringRef> subregs;
};

map<pair<RegKind, unsigned>, RegData> reg_map = makeRegMap(); // whichever kind of a map
// or possibly, map<RegKind, map<unsigned, RegData>> = ...

for (const auto &kv : reg_map)
  subreg_name_set.insert(kv.second.subregs.begin(), kv.second.subregs.end());

for (const auto &x : llvm::enumerate(regs)) {
  llvm::StringRef reg_name = x.value().name.GetStringRef();
  if (llvm::is_contained(subreg_name_set, reg_name))
    return;
  if (Optional<pair<RegKind, size_t>> reg = get_reg(reg_name))
    reg_map[reg].index = x.index(); 
}

...

This would allow us to factor out two tedious jobs (constructing the register map and identifying registers) into separate functions, leaving only the only (simplified, I hope) core logic for the main function. The get_reg function could use whichever method is easiest for the translation of register names, or even a combination of methods (a StringSwitch for gprs and some consume_fronts for the regularly-named registers).

WDYT?

lldb/source/Plugins/ABI/X86/ABIX86.cpp
171 ↗(On Diff #380058)

For a simple list like this, I'd probably remove the trailing comma to have clang-format format it more succinctly.

mgorny marked an inline comment as done.Oct 18 2021, 5:25 AM

I'm not sure what exactly you're proposing and whether your proposal would work but I think it's a step in the right direction.

Let's start by reiterating what we need:

  1. A way to iterate over all subregisters of given RegKind, sorted by base register index, yielding base register index and subregister name (map<RegKind, vector<...>>.
  2. A way to match register name against all *expected* subregisters in order to abort if any of them exists (set<StringRef>).
  3. A way to match register name against all known base registers and store their indices (map<StringRef, ...>).
  4. We should be able to construct all of the above from some readable input.
lldb/source/Plugins/ABI/X86/ABIX86.cpp
171 ↗(On Diff #380058)

Heh, I was wondering why clang-format chooses one format sometimes, and the other sometimes but it wouldn't occur to me that it's due to the trailing comma ;-).

mgorny updated this revision to Diff 380366.Oct 18 2021, 6:21 AM
mgorny marked an inline comment as done.
mgorny retitled this revision from [lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm* to [lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm* [WIP].

WIP alternative approach.

I think I like this.

lldb/source/Plugins/ABI/X86/ABIX86.cpp
261 ↗(On Diff #380366)

llvm::Optional gives you this assert for free.

321 ↗(On Diff #380366)

It would be nice to have some comment explaining the purpose of this variable (I guess its there to ensure matching register order).

mgorny marked 2 inline comments as done.Oct 18 2021, 9:23 AM
mgorny updated this revision to Diff 380453.Oct 18 2021, 10:03 AM
mgorny retitled this revision from [lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm* [WIP] to [lldb] [ABI/X86] Support combining xmm* and ymm*h regs into ymm*.

Major refactoring of the generator function.

labath accepted this revision.Oct 19 2021, 12:24 AM

Looks good. Thanks for your patience.

lldb/source/Plugins/ABI/X86/ABIX86.cpp
36–52 ↗(On Diff #380453)

anonymous namespace here

This revision is now accepted and ready to land.Oct 19 2021, 12:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 19 2021, 1:31 AM