Includes the syntax for the immediate offset field of load and store instructions, but doesn't pattern-match anything other than 0 yet.
Details
Diff Detail
Event Timeline
lib/Target/WebAssembly/WebAssemblyInstrMemory.td | ||
---|---|---|
106 | writing the offset operand as 'imm:$off' turns out to be critical here to getting an immediate in the output. If you say just $off or I32:$off you still get a pattern match but it generates an i32.const and uses that instead of putting it directly as an immediate in the store instruction. (The same applies if you use this kind of pattern to match a load, but if you put it directly in the definition for the load as I did here, then it doesn't matter if you use the imm: prefix or not). I'm not sure why that is. |
This looks like a good direction. I like how it uses def : Pat instead of needing custom code in WebAssemblyISelDAGToDAG.cpp :-).
One tricky thing though is that wasm's constant offsets are unsigned, so we can't support negative values. I think we'll need to add a predicate on the pattern-match which checks this. I think it's fine if you'd prefer to just add a FIXME for this for now and we can address it later though. Or if you want to simplify things, we could also defer pattern-matching for constant offsets altogether for now, since framepointer lowering doesn't actually require it.
lib/Target/WebAssembly/WebAssemblyInstrMemory.td | ||
---|---|---|
106 | If you say I32:$off, it refers to the I32 register class (defined in lib/Target/WebAssembly/WebAssemblyRegisterInfo.td), which effectively says that you need the value in a register of that class, which forces the instruction selector to use an i32.const to get the value into a register. I don't know the rules if you just say $off by itself. I'd suggest using the imm: prefix to avoid trouble :-). |
Agreed.
One tricky thing though is that wasm's constant offsets are unsigned, so we can't support negative values. I think we'll need to add a predicate on the pattern-match which checks this.
We'll also want to optimize things so that LLVM knows to generate positive offsets instead of negative ones (post-increment as much as possible). Do you know if there's a knob for that? It's just an optimization so maybe just mention it in the list of work to do in the README?
and we can address it later though.
I see what you did there, "address". :o)
We'll also want to optimize things so that LLVM knows to generate positive offsets instead of negative ones (post-increment as much as possible). Do you know if there's a knob for that? It's just an optimization so maybe just mention it in the list of work to do in the README?
The main hook we can use is WebAssemblyTargetLowering::isLegalAddressingMode, and there's a TODO for it in WebAssemblyInstrMemory.md.
Updated to include all loads and stores, and remove the pattern match for now.
I couldn't figure out a way to constrain the match for unsigned immediates with just tablegen yet.
writing the offset operand as 'imm:$off' turns out to be critical here to getting an immediate in the output. If you say just $off or I32:$off you still get a pattern match but it generates an i32.const and uses that instead of putting it directly as an immediate in the store instruction. (The same applies if you use this kind of pattern to match a load, but if you put it directly in the definition for the load as I did here, then it doesn't matter if you use the imm: prefix or not). I'm not sure why that is.