Initial SPARC compilation test

Gilles Duboscq duboscq at ssw.jku.at
Mon Jun 3 01:28:30 PDT 2013


I'm also in favour of the .emit(masm) method, it allows you to keep the
various benefits mentioned above and would remove the surprise element of
side-effecting constructors.

-Gilles


On Wed, May 29, 2013 at 6:16 PM, Christian Thalinger <
christian.thalinger at oracle.com> wrote:

>
> On May 29, 2013, at 7:56 AM, Morris Meyer <morris.meyer at oracle.com> wrote:
>
> > 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.
>
> I wonder if this is still true with newer SPARC implementations.
>
> -- Chris
>
> >
> > 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