This is an archive of the discontinued LLVM Phabricator instance.

Add an MCTargetMachine and have it construct MC classes.
AbandonedPublic

Authored by dsanders on Oct 19 2015, 3:37 AM.

Details

Summary

All targets require a registered MCTargetMachine, even if it's just
MCTargetMachine itself.

This patch uses the Triple as the representation for the target but follow
up patches will start to break this up on a per-target basis.

A corresponding patch to clang will be committed along with this. The patch
is similar to the patches in the tools in ./tools/....

MCRelocationInfo, and MCSymbolizer has been left out of this patch since
they require special care to avoid a circular dependency between MC and
MCDisassembler.

Diff Detail

Event Timeline

dsanders updated this revision to Diff 37731.Oct 19 2015, 3:37 AM
dsanders retitled this revision from to Add an MCTargetMachine and have it construct MC classes..
dsanders updated this object.
dsanders added subscribers: echristo, rengolin, llvm-commits.
dsanders added inline comments.Oct 19 2015, 3:51 AM
lib/Target/X86/Disassembler/X86Disassembler.cpp
993

I just noticed this redundant std::move(). I'll remove it since it's a leftover from when createX86Disassembler() created it's own redundant copy of MCInstrInfo.

dsanders updated this revision to Diff 40428.Nov 17 2015, 1:51 PM

Refreshed patch.
During this rebase I hit a use-after-free bug in the change to
createMCDisassembler(). The change was to use the callers MCInstrInfo instead
of creating another one (only X86 and Hexagon did this) but it seems the
callers MCInstrInfo isn't preserved as long as it used to be. I've reverted
that change for now and I'll revisit it later.

dsanders updated this revision to Diff 40499.Nov 18 2015, 6:19 AM
dsanders edited edge metadata.

Virtualize each of the MCTargetMachine::create*() functions. The following
patches were going to do it anyway and doing it in this patch means that as
long as this patch makes it into LLVM 3.8, the later work can potentially
be merged without breaking the library ABI.

Hi,

Can you explain why you are making this change?

This patch series is the beginning of another attempt to resolve the GNU Triple
problems discussed ~4 months ago in "The Trouble with Triples"
(http://lists.llvm.org/pipermail/llvm-dev/2015-July/087700.html). The linked
thread goes into several problems which these patches set up a solution for.
It's a long read so I've tried to include all the important bits below.

At the moment, the Triple is used to configure the MC-layer classes. D13863
highlights a few examples for the MCAsmInfo subclasses:

  • Several targets infer the endianness from the Triple.
  • A few targets select between MCAsmInfo subclasses depending on the triple.
    • Each possible implementation needs to know different things.
  • ARM infers the exception handling mechanism from the triple.
  • Mips infers ABI information such as the pointer size and stack slot size from the triple.
  • A few targets infer 32/64-bit from the triple.
  • A couple targets infer behaviour from the OS X version in the triple.
  • Several targets don't need to know anything in particular.
  • etc.

Despite having different information requirements, each subclass is required to
have a factory function with the same function type (MCAsmInfoCTorFnTy) even
though this is not publicly visible (there's no public accessor for
MCAsmInfoCtorFn). One of these arguments is the Triple which is both
ambiguous and incomplete. Here are a couple examples for MIPS:

  • Mips triples do not contain information about the ABI.
  • Mips triples seem to contain information about the endian, 32/64-bit, etc. but it's generally subject to being overridden by distribution defaults and by command line options.

I've only given examples for Mips but ARM has a similar degree of ambiguity and
even X86 has some.

My first attempt at solving this was simply to replace Triple objects with a
TargetTuple that provided the same interface but wasn't ambiguous. The
Triple ambiguity was handled in a single controlled point in the code.
This plan was also going to solve some other problems (mostly related to
generating 32-bit code on a 64-bit Mips CPU). Unfortunately for me, this met
opposition but the result of those discussions is the MCTargetMachine.

My intent with this patch series is to make MCTargetMachine (and its
target-specific subclasses) both factories for MC-layer classes and a
representation of the target those MC-layer classes should be configured for.
It will be initialized by the Triple and then mutated into the desired target
by distribution defaults, command line options, etc.. For example, clang would do this:

// Create a MCTargetMachine for Mips using the default ABI for the triple (o32).
MCTargetMachine *MTM = Target->createMCTargetMachine(Triple("mips-linux-gnu"));
...
// Process -EL option
MipsMCTargetMachine *MipsMTM = static_cast<MipsMCTargetMachine *>(MTM);
MipsMTM->setEndian(LittleEndian);
...
// Process -mabi=64 option
MipsMCTargetMachine *MipsMTM = static_cast<MipsMCTargetMachine *>(MTM);
MipsMTM->setABI("n64");
...
// Create MC layer objects as usual.
MTM->createMCAsmInfo(MRI)

This solves the ambiguity problem by merging Triples, distribution defaults,
and command line options into a single target description. It also solves the
problem of each target needing different information since the MCTargetMachine
subclasses can contain information not present in the Triple and the overridden
createMCAsmInfo() only has to comply with the public interface.

The three patches posted so far are mainly concerned with the factory side of things. If they're accepted then I'll start working on the mutation side.

dsanders abandoned this revision.Jul 18 2019, 7:07 PM