[llvm-dev] MachineIRBuilder API

Aditya Nandakumar via llvm-dev llvm-dev at lists.llvm.org
Wed Jan 30 19:07:16 PST 2019

Hi Matt

Regarding composability, this is already possible (If I understand

Builder.buildInstr(Opcode1, {SomeDst}, { Builder.buildConstant(..),

For the vast majority of the cases, there is one definition register for
each instruction, and it implicitly calls getOperand(0).getReg(0) for you.

On Wed, Jan 30, 2019 at 4:56 PM Arsenault, Matthew via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hi,
> I’m finding the API for MachineIRBuilder to be pretty annoying to use
> compared to SelectionDAG. I think it’s making the majority of code more
> verbose and unwieldly for anything less than trivial. I think changing it
> to behave more like the DAG.get* functions would make it easier to use, and
> decrease the mental overhead when porting code from SelectionDAG.
> The main issue is needing to create and/or manage the registers used
> separately from the instruction creation. Normally you have to create a
> generic virtual register with the correct output type. When a lot of
> intermediate values are needed, this can get pretty messy. There is an
> alternative provided, but I don’t think it’s really any better. You can
> construct a DstOp from an LLT, which will create a new register. You would
> then need to use the returned instruction, get the destination register
> from the output and use that. This doesn’t allow you to naturally compose
> operations by using the return value of a build* function to another. I
> also find this aspect to be pretty error prone, as I discovered it by
> accident when the registers I had already created weren’t being used.
> The current set of build* functions all return MachineInstrBuilder, or
> effectively the inserted instruction. This seems reasonable for some odd
> low level cases where you are building an instruction that won’t be
> inserted yet, or you don’t know the operands ahead of time. For the
> majority of code, I don’t see how this is useful. Most places should be
> using a buildFooInstr type of instruction, which creates and inserts a
> specific opcode (or set of similar behaving opcodes) with all of the
> necessary operands. The instruction is already inserted, and can’t have
> additional operands added, so there isn’t really anything to do with it.
> It would be more helpful if these were returning the register / logical
> value, similar to what you get with DAG.getNode(). In the odd case you
> actually want the instruction, you could check the instruction before the
> insert point.
> Does anyone feel strongly that these functions should be returning the
> builder? What I would like to do is either replace and complete the current
> set of buildOpcode functions with ones which return the output register
> value, or add an alternative set which do. Is it worth having two sets of
> functions (a buildFoo and getFoo set?). The same issue applies with opcodes
> producing multiple results, such as buildUnmerge, but in that case I would
> probably change these to a SmallVectorImpl out argument.
> Another minor issue I’ve run into is when trying to add convenience
> functions with constants (e.g. shift creation with materializing the amount
> constant). With an overload using a SrcOp constructible from “unsigned”,
> and one using an integer type, the wrong one gets called and ends up
> creating a constant with the value of the register. I think this is more a
> symptom of using a plain unsigned for registers, but fixing this
> longstanding mistake everywhere would be a very large project.
> -Matt
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190130/9e289d51/attachment.html>

More information about the llvm-dev mailing list