Initial SPARC compilation test
Morris Meyer
morris.meyer at oracle.com
Wed May 29 07:56:45 PDT 2013
The object layout of instructions has sort of grown on me. I think the
possibility for post-assembly reordering of code - such as this from the
SPARC V9 spec below could have benefits.
I think there is room for improvement still in SPARCAssembler with the
class structure - saving the fields and separating encode from emit
seems to be one.
For now though I'm working on getting Graal to compile on SPARC.
--mm
Branches cause most implementations’ performance to degrade
significantly. Frrequently, the MOVcc and FMOVcc instructions can be
used to avoid branches. For example, the following C language segment:
double A, B, X;
if (A > B) then X = 1.03; else X = 0.0;
can be coded as
! assume A is in %f0; B is in %f2; %xx points to constant area
ldd [%xx+C_1.03],%f4 ! X = 1.03
fcmpd %fcc3,%f0,%f2 ! A > B
fble,a %fcc3,label
! following only executed if the branch is taken
fsubd %f4,%f4,%f4 ! X = 0.0
label:...
This takes four instructions including a branch. Using FMOVcc, this
could be coded as
ldd [%xx+C_1.03],%f4 ! X = 1.03
fsubd %f4,%f4,%f6! X’ = 0.0
fcmpd %fcc3,%f0,%f2! A > B
fmovdle %fcc3,%f6,%f4! X = 0.0
This also takes four instructions, but requires no branches and may
boost performance significantly. It is sug- gested that MOVcc and FMOVcc
be used instead of branches wherever they would improve performance.
SPARCV9
On 5/28/13 6:27 PM, Christian Thalinger wrote:
> On May 28, 2013, at 1:58 PM, Doug Simon <doug.simon at oracle.com> wrote:
>
>> On May 28, 2013, at 10:52 PM, Thomas Wuerthinger <thomas.wuerthinger at oracle.com> wrote:
>>
>>> The possible benefits of having instruction classes would include abilities like writing simulation or verification code.
>> True. It also makes the classes usable as output for a structured disassembler.
> That's a good point. Instruction patching could then be something like:
>
> Add.readAt(pc).setRd(reg).emit(masm);
>
> Since RISC architectures usually have a small number of instruction classes I think we should go that way.
>
> -- Chris
>
>>> This would include the field definitions you outline below. In the machine code, it would not make any performance difference as escape analysis would still get rid of the allocation for the case where the instruction instance is not stored in a side data structure.
>> Yes, I have complete faith in escape analysis, especially in this case.
>>
>>> If we do not have the fields, then I see no benefit of using constructors over static methods.
>> Right. The use cases mentioned above are interesting however though.
>>
>> -Doug
>>
>>> On May 28, 2013, at 10:42 PM, Doug Simon <doug.simon at oracle.com> wrote:
>>>
>>>> On May 28, 2013, at 10:28 PM, Thomas Wuerthinger <thomas.wuerthinger at oracle.com> wrote:
>>>>
>>>>> In general, I like the idea of representing the instructions using a Java class hierarchy. What about using a pattern like new InstructionXY(…).emit(…) to avoid the side-effecting constructor?
>>>> This make the Fmt classes bigger as they would define fields for the operands and they need to define an emit() method. For example, we currently we have:
>>>>
>>>> public static class Fmt3b {
>>>> public Fmt3b(SPARCAssembler masm, int op, int op3, int rs1, int regOrImmediate, int rd) {
>>>> assert op == 2 || op == 3;
>>>> assert op3 >= 0 && op3 < 0x40;
>>>> assert rs1 >= 0 && rs1 < 0x20;
>>>> assert rd >= 0 && rd < 0x20;
>>>>
>>>> masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | (regOrImmediate & 0x1fff));
>>>> }
>>>> }
>>>>
>>>> public static class Add extends Fmt3b {
>>>> public Add(SPARCAssembler masm, Register src1, int simm13, Register dst) {
>>>> super(masm, Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), simm13, dst.encoding());
>>>> }
>>>> public Add(SPARCAssembler masm, Register src1, Register src2, Register dst) {
>>>> super(masm, Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), src2.encoding(), dst.encoding());
>>>> }
>>>> }
>>>>
>>>> and we would go to:
>>>>
>>>> public static class Fmt3b {
>>>> final int op;
>>>> final int op3;
>>>> final int rs1;
>>>> final int regOrImmediate;
>>>> int rd;
>>>> public Fmt3b(int op, int op3, int rs1, int regOrImmediate, int rd) {
>>>> assert op == 2 || op == 3;
>>>> assert op3 >= 0 && op3 < 0x40;
>>>> assert rs1 >= 0 && rs1 < 0x20;
>>>> assert rd >= 0 && rd < 0x20;
>>>> this.op = op;
>>>> this.op3 = op3;
>>>> this.rs1 = rs1;
>>>> this.regOrImmediate = regOrImmediate;
>>>> }
>>>> public emit(SPARCAssembler masm) {
>>>> masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | (regOrImmediate & 0x1fff));
>>>> }
>>>> }
>>>>
>>>> public static class Add extends Fmt3b {
>>>> public Add(SPARCAssembler masm, Register src1, int simm13, Register dst) {
>>>> super(Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), simm13, dst.encoding());
>>>> }
>>>> public Add(SPARCAssembler masm, Register src1, Register src2, Register dst) {
>>>> super(Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), src2.encoding(), dst.encoding());
>>>> }
>>>> }
>>>>
>>>> If we do without instruction classes, we'd have:
>>>>
>>>> void fmt3b(int op, int op3, int rs1, int regOrImmediate, int rd) {
>>>> assert op == 2 || op == 3;
>>>> assert op3 >= 0 && op3 < 0x40;
>>>> assert rs1 >= 0 && rs1 < 0x20;
>>>> assert rd >= 0 && rd < 0x20;
>>>>
>>>> emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | (regOrImmediate & 0x1fff));
>>>> }
>>>>
>>>> void add(Register src1, int simm13, Register dst) {
>>>> fmt3b(Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), simm13, dst.encoding());
>>>> }
>>>>
>>>> void add(Register src1, Register src2, Register dst) {
>>>> super(Ops.ArithOp.getValue(), Op3s.Add.getValue(), src1.encoding(), src2.encoding(), dst.encoding());
>>>> }
>>>>
>>>> As long as the above are non-static methods in SPARCAssembler, we still have extensibility with less code.
>>>>
>>>> -Doug
>>>>
>>>>> - thomas
>>>>>
>>>>> On May 28, 2013, at 8:59 PM, Doug Simon <doug.simon at oracle.com> wrote:
>>>>>
>>>>>> On May 28, 2013, at 7:48 PM, Christian Thalinger <christian.thalinger at oracle.com> wrote:
>>>>>>
>>>>>>> On May 25, 2013, at 2:07 PM, Doug Simon <doug.simon at oracle.com> wrote:
>>>>>>>
>>>>>>>> Hi Morris,
>>>>>>>>
>>>>>>>> On May 25, 2013, at 3:57 PM, Morris Meyer <morris.meyer at oracle.com> wrote:
>>>>>>>>
>>>>>>>>> Christian suggested that we use Fmt superclasses to contain the various SPARC instruction modes. I think his preference would be to generate the assembler w annotations but this is as far as we pushed it.
>>>>>>> Yes, this is my fault. Don't blame Morris :-)
>>>>>> Blame? I had no intention of assigning blame ;-) Just trying to understand the advantage(s) of doing it this way.
>>>>>>
>>>>>>>> As part of the Maxine project, we had a system for generating assemblers[1] (with which we generated assemblers for SPARC and x64). This system also allowed for easy construction of disassemblers. There might something there worth leveraging if we want to pursue the generated assembler idea further. I know Christian is already aware of this work - I'm just bringing it up in case others aren't.
>>>>>>> Right. Remind me, why was it not used in the end?
>>>>>> Because the port of C1 into C1X was intended to be as disconnected from existing Maxine technology as possible (to demonstrate the runtime/compiled interface designed as part of the porting process). Had we not moved onto Graal, there were thoughts of having the hand assembler in C1X be generated by the framework.
>>>>>>
>>>>>>>>> I started w static methods like the PTX and AMD64 assemblers but this pattern is sort of growing on me as makes asserting things easier.
>>>>>>>> The assertions I see in SPARCAssembler could just as easily be placed in helper methods as opposed to super class constructors right?
>>>>>>> It could. It seems like a good idea to use the Java class hierarchy to represent the instruction classes of an ISA but if it causes too much trouble then we can drop it.
>>>>>> I have no strong preference. I was just looking for the technical advantage of modeling the instructions with classes that motivated the use of side-effecting constructors.
>>>>>>
>>>>>> In any case, it's great to see a second backend being added to Graal.
>>>>>>
>>>>>> -Doug
>>>>>>
>>>>>>> -- Chris
>>>>>>>
>>>>>>>>> The warning is handled in the lir.sparc package with a JDT prefs change.
>>>>>>>> Unfortunately this doesn't help anyone using mx to create the Eclipse project configurations. The next time anyone runs 'mx eclipseinit' (which most of us do after a pull when we new projects added), your changes to graal/com.oracle.graal.lir.sparc/.settings/org.eclipse.jdt.core.prefs will be overwritten.
>>>>>>>>
>>>>>>>> For now, could you please add @SuppressWarnings("unused") where necessary and hg delete graal/com.oracle.graal.lir.sparc/.settings/org.eclipse.jdt.core.prefs. At the same time, we should consider whether to disable the unusedObjectAllocation check globally. As of now, we use the same Eclipse settings for all projects and I'm not sure this current case is a strong enough reason to deviate from that policy. Especially since it's not yet clear (to me at least) why the pattern of separate
>>>>>>>>
>>>>>>>> -Doug
>>>>>>>>
>>>>>>>> [1] https://wikis.oracle.com/display/MaxineVM/Assembler
>>>>>>>>
>>>>>>>>> --mm
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On May 25, 2013, at 5:54 AM, Doug Simon <doug.simon at oracle.com> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Morris, Christian,
>>>>>>>>>>
>>>>>>>>>> Why is the SPARC assembler constructed as a set of classes, one for each instruction as opposed to a single assembler class with a bunch of methods (like AMD64Assembler)? I trust that escape analysis does the right thing so there's no overhead for the object construction but I don't see any real advantages to doing it this way. It's strange to have a constructor with a side effect. And of course, it means we need to suppress the Eclipse warnings somehow.
>>>>>>>>>>
>>>>>>>>>> -Doug
>>>>>>>>>>
>>>>>>>>>> On May 25, 2013, at 5:24 AM, Morris Meyer <morris.meyer at oracle.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> I just pushed the initial SPARC compilation test for Graal.
>>>>>>>>>>>
>>>>>>>>>>> ./mx.sh --vm server unittest BasicSPARCTest
>>>>>>>>>>>
>>>>>>>>>>> will get you started.
>>>>>>>>>>>
>>>>>>>>>>> --mm
More information about the graal-dev
mailing list