[LLVMdev] [REQUEST FOR FEEDBACK] Inline asm multiple alternative constraints

Dale Johannesen dalej at apple.com
Thu Aug 26 19:23:37 PDT 2010

On Aug 25, 2010, at 12:45 PM, John Thompson wrote:

> Hi,
> I'm looking for some feedback on the changes represented in the  
> attached patches, which I'll describe below.
> I'm sending this to both the LLVM and Clang list because it affects  
> both, though the main focus here is LLVM.
> Basically, I've partially implemented some changes for choosing  
> multiple alternative constraints largely on the LLVM side.
> The Clang change is to output the multiple constraints using a '|'  
> character in the constraint strings to delimit the alternatives.

This part is simple, and it can't be worse than it is now.

> The LLVM change is as follows.
> In an earlier attempt, I just hacked up  
> SelectionDAGBuilder::visitInlineAsm, and pretty much used the same  
> logic in TargetLowering::ComputeConstraintToUse/ChooseConstraint.   
> But then I discovered that InlineAsm::ParseConstraints was called in  
> a couple of other places, and in one of those places  
> (IsOperandAMemoryOperand in AddrModeMatcher.cpp), there wasn't a DAG  
> pointer handy (at least I don't think there is, as I'm not too  
> familiar yet with LLVM internals), which meant that I needed to  
> handle multiple alternative constraints in other places besides just  
> SelectionDAGBuilder::visitInlineAsm.

That's too bad, I didn't know about the AddrModeMatcher reference.  I  
don't see a DAG pointer either; it seems to be an argument in some  
places.  Regardless,  unifying the three loops that do pretty much the  
same thing is surely a good idea.

>  Basically I see that there are three layers of contraint info  
> classes, SDISelAsmOperandInfo -> AsmOperandInfo -> ConstraintInfo.   
> Therefore, I implemented a different scheme, putting a  
> ParseConstraints function in TargetLowering that returns a vector of  
> AsmOperandInfo objects, and which will do the constraint selection  
> without needing the DAG.  I'm assuming the value info in the  
> operands from the callsite object is sufficient to choose the  
> constraints.  I also added some other virtual functions to  
> TargetLowering to allow the different targets to handle the target- 
> specific contraints.  At present, I only overrode the  
> getSingleConstraintMatchWeight function in X86TargetLowering, and  
> just for one constraint letter, as an example.
> In the three places where the original InlineAsm::ParseConstraints  
> was called (CodeGenPrepare.cpp, AddrModeMatcher.cpp, and  
> SelectionDAGBuilder), I replaced the calls with calls to  
> TargetLowering::ParseConstraints, and revised the loops over the  
> constraints accordingly, which were still needed to set up  
> SDISelAsmOperandInfo objects or get other information the code was  
> looking for.  SelectionDAGBuilder::visitInlineAsm I especially  
> reordered bit at the front, to make things work.  I left in a little  
> bit of overlap in the setting of the CallOperandVal member in the  
> first for loop, which I could factor out, as I really just need the  
> output and input counts.
> Bascially, I wanted to get some feedback before I went too much  
> farther down this road.

I don't have that good a sense of good class design, but this looks OK  
to me.

> I think the main work left is to add support for all or some subset  
> of both the generic and target-specific constraints, and to write  
> tests for them all.
> Since I had trouble with running tests on a Windows box, I set up a  
> Linux box so I could run the regression tests.  The tests still pass  
> with these changes.

Those tests don't include any for multiple alternative constraints,  
since the expectation is the llvm-gcc FE will have removed them.  You  
should really run the gcc testsuite as well; that's a much better test  
of inline asm.  If you get this working right there should be some new  
passes.  I'm not sure how to run it using clang as the compiler, but I  
think Daniel got it to work.

> So, my main question is, am I on the right track?  And either way,  
> specific information on problems would be appreciated too.
> Another question concerns the weighting I used for choosing the  
> constraints.  Bascially I pretty much used the same prioritization  
> used in TargetLowering::ComputeConstraintToUse/ChooseConstraint,  
> which will chose memory operands over register.  I would have  
> thought a register operand would have been a better choice over  
> memory, but then that raises the question of whether you can know  
> what's already in a register when this instruction is reached.  I  
> haven't gotten deep enough to know yet.  I assume it's like this  
> because it is more likely to be a correct fit, if not optimal.

I think it's that it's possible to run out of registers if you pick  
"r" for a large number of "rm" constraints.  This mainly affects asm  
blocks, where you have hundreds of lines of asm in a single statement.

> It seems that if the value info in the operands from the callsite  
> object is sufficient to choose the constraints, the  
> ComputeConstraintToUse/ChooseConstraint function could also use this  
> scheme, probably just calling the same get weight functions, to be a  
> bit more efficient.  I left it alone for now, because I know it  
> works as it is.

Thanks for working on this.

More information about the llvm-dev mailing list