Support for out-of-tree targets?

Are purely out-of-tree targets supported? A search in Discourse didn’t return much relevant or up-to-date information on the topic. While the target-dependent class hierarchy is designed to allow a backend to implement subclasses within the confines of its own llvm/lib/Target/ subdirectory, there are a number of puzzle pieces that are not as well decoupled. Here are a (most likely incomplete) list of issues I found:

  1. Enum types like Triple, MVT and ValueType are maintained by hand, and seem to require intrusive in-tree changes if I were to add an out-of-tree target.

  2. The llvm::Intrinsic enum is generated by TableGen, which we can teach to read input from an out-of-tree target source directory, but the target-specific Intrinsic enums are sometimes used in common code (usually under Analysis, CodeGen, and Transforms), and such uses may not properly delegate unrecognized cases to the target properly.

  3. ELF and DWARF support similarly depends on hand-written enums. The implementation does not seem modularized; much of the code consists of switch statements, and adding a new target requires adding case statements in a whole bunch of places.

  4. lld and Clang have more, bigger, issues of similar nature, but let’s just discuss LLVM for now.

I understand that most of the time, when we talk about “out-of-tree target”, we really mean “downstream fork of the whole tree with a new target”. But was LLVM ever intended to be able to support a purely out-of-tree target, and if so, should we try to rebuild and maintain that ability? Or if it still has that ability, can someone point me to a user guide?

Thanks!

2 Likes

Hello

As far as I remember (with my memories going back to 2005), LLVM never supported “pluggable” backends / targets.

Thanks for the reply @akorobeynikov. Are you aware of any historical attempt at that design? If there was a discussion around this question, what was the rationale for not supporting pluggable backends? It seems that it would be achievable with just a tad more effort.

I’m not aware of one. Backends can be “disabled” if not necessary, but not plugged in. So, no rationale at all – it was just done this way :slight_smile: Given the things you correctly outlined, it will not be a trivial thing.

Anton has better historical context than I do, but my sense is that LLVM is designed to be extensible to new targets, but is not designed to be pluggable. We have a goal of factoring as much target-specific logic as possible into target-specific libraries, but there are many ways that we fall short of this goal. Bryan mentioned several.

1 Like