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
235

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
235

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
300

llvm::Optional gives you this assert for free.

360

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–64

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