graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java

Print this page




  30 
  31 import com.oracle.graal.api.code.*;
  32 import com.oracle.graal.api.meta.*;
  33 import com.oracle.graal.asm.*;
  34 import com.oracle.graal.compiler.gen.*;
  35 import com.oracle.graal.compiler.target.*;
  36 import com.oracle.graal.debug.*;
  37 import com.oracle.graal.graph.*;
  38 import com.oracle.graal.lir.*;
  39 import com.oracle.graal.lir.StandardOp.JumpOp;
  40 import com.oracle.graal.lir.hsail.*;
  41 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack;
  42 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Reg;
  43 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Stack;
  44 import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp;
  45 import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp;
  46 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
  47 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp;
  48 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
  49 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;


  50 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
  51 import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
  52 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp;
  53 import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp;
  54 import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;


  55 import com.oracle.graal.nodes.*;
  56 import com.oracle.graal.nodes.calc.*;
  57 import com.oracle.graal.nodes.java.*;


  58 
  59 /**
  60  * This class implements the HSAIL specific portion of the LIR generator.
  61  */
  62 public class HSAILLIRGenerator extends LIRGenerator {
  63 




  64     public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
  65 
  66         @Override
  67         public LIRInstruction createMove(AllocatableValue dst, Value src) {
  68             if (src instanceof HSAILAddressValue) {
  69                 return new LeaOp(dst, (HSAILAddressValue) src);
  70             } else if (isRegister(src) || isStackSlot(dst)) {
  71                 return new MoveFromRegOp(dst, src);
  72             } else {
  73                 return new MoveToRegOp(dst, src);
  74             }
  75         }
  76     }
  77 
  78     public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
  79         super(graph, runtime, target, frameMap, cc, lir);
  80         lir.spillMoveFactory = new HSAILSpillMoveFactory();
  81     }
  82 
  83     @Override


 106                 return true;
 107         }
 108     }
 109 
 110     @Override
 111     public Variable emitMove(Value input) {
 112         Variable result = newVariable(input.getKind());
 113         emitMove(result, input);
 114         return result;
 115     }
 116 
 117     @Override
 118     public void emitMove(AllocatableValue dst, Value src) {
 119         if (isRegister(src) || isStackSlot(dst)) {
 120             append(new MoveFromRegOp(dst, src));
 121         } else {
 122             append(new MoveToRegOp(dst, src));
 123         }
 124     }
 125 








 126     public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) {
 127         AllocatableValue baseRegister;
 128         long finalDisp = displacement;
 129 
 130         if (isConstant(base)) {
 131             if (asConstant(base).isNull()) {
 132                 baseRegister = Value.ILLEGAL;
 133             } else if (asConstant(base).getKind() != Kind.Object) {
 134                 finalDisp += asConstant(base).asLong();
 135                 baseRegister = Value.ILLEGAL;
 136             } else {
 137                 baseRegister = load(base);
 138             }
 139         } else if (base == Value.ILLEGAL) {
 140             baseRegister = Value.ILLEGAL;
 141         } else {
 142             baseRegister = asAllocatable(base);
 143         }
 144         if (index != Value.ILLEGAL) {
 145             if (isConstant(index)) {


 154                     indexRegister = convertedIndex;
 155                 }
 156                 if (baseRegister == Value.ILLEGAL) {
 157                     baseRegister = asAllocatable(indexRegister);
 158                 } else {
 159                     baseRegister = emitAdd(baseRegister, indexRegister);
 160                 }
 161             }
 162         }
 163         return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp);
 164     }
 165 
 166     private HSAILAddressValue asAddress(Value address) {
 167         if (address instanceof HSAILAddressValue) {
 168             return (HSAILAddressValue) address;
 169         } else {
 170             return emitAddress(address, 0, Value.ILLEGAL, 0);
 171         }
 172     }
 173 




 174     @Override
 175     public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) {
 176         HSAILAddressValue loadAddress = asAddress(address);
 177         Variable result = newVariable(kind);
 178         append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null));







 179         return result;
 180     }
 181 
 182     @Override
 183     public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) {
 184         HSAILAddressValue storeAddress = asAddress(address);

 185         Variable input = load(inputVal);
 186         append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null));





 187     }
 188 
 189     @Override
 190     public Variable emitAddress(StackSlot address) {
 191         throw new InternalError("NYI");
 192     }
 193 
 194     @Override
 195     public void emitJump(LabelRef label) {
 196         append(new JumpOp(label));
 197     }
 198 
 199     private static HSAILCompare mapKindToCompareOp(Kind kind) {
 200         switch (kind) {
 201             case Int:
 202                 return ICMP;
 203             case Long:
 204                 return LCMP;
 205             case Float:
 206                 return FCMP;


 443         return result;
 444     }
 445 
 446     @Override
 447     public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) {
 448         throw new InternalError("NYI");
 449     }
 450 
 451     @Override
 452     public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) {
 453         throw new InternalError("NYI");
 454     }
 455 
 456     @Override
 457     public Variable emitAnd(Value a, Value b) {
 458         Variable result = newVariable(a.getKind());
 459         switch (a.getKind()) {
 460             case Int:
 461                 append(new Op2Stack(IAND, result, a, loadNonConst(b)));
 462                 break;



 463             default:
 464                 throw GraalInternalError.shouldNotReachHere();
 465         }
 466         return result;
 467     }
 468 
 469     @Override
 470     public Variable emitOr(Value a, Value b) {
 471         throw new InternalError("NYI");
 472     }
 473 
 474     @Override
 475     public Variable emitXor(Value a, Value b) {
 476         throw new InternalError("NYI");
 477     }
 478 
 479     @Override
 480     public Variable emitShl(Value a, Value b) {
 481         Variable result = newVariable(a.getKind());
 482         switch (a.getKind()) {
 483             case Int:
 484                 append(new ShiftOp(ISHL, result, a, b));
 485                 break;



 486             default:
 487                 GraalInternalError.shouldNotReachHere();
 488         }
 489         return result;
 490     }
 491 
 492     @Override
 493     public Variable emitShr(Value a, Value b) {
 494         throw new InternalError("NYI");
 495     }
 496 
 497     @Override
 498     public Variable emitUShr(Value a, Value b) {
 499         Variable result = newVariable(a.getKind());
 500         switch (a.getKind()) {
 501             case Int:
 502                 append(new ShiftOp(IUSHR, result, a, b));
 503                 break;



 504             default:
 505                 GraalInternalError.shouldNotReachHere();
 506         }
 507         return result;
 508     }
 509 
 510     @Override
 511     public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
 512         Variable input = load(inputVal);
 513         Variable result = newVariable(opcode.to);
 514         switch (opcode) {
 515             case I2F:
 516                 append(new Op1Stack(I2F, result, input));
 517                 break;
 518             case I2L:
 519                 append(new Op1Stack(I2L, result, input));
 520                 break;
 521             case I2D:
 522                 append(new Op1Stack(I2D, result, input));
 523                 break;


 544         append(new ReturnOp(Value.ILLEGAL));
 545     }
 546 
 547     @Override
 548     public void emitMembar(int barriers) {
 549         throw new InternalError("NYI");
 550     }
 551 
 552     @Override
 553     protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
 554         throw new InternalError("NYI");
 555     }
 556 
 557     @Override
 558     protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
 559         throw new InternalError("NYI");
 560     }
 561 
 562     @Override
 563     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {











 564         throw new InternalError("NYI emitForeignCall");





 565     }
 566 
 567     @Override
 568     public void emitBitCount(Variable result, Value value) {
 569         if (value.getKind().getStackKind() == Kind.Int) {
 570             append(new HSAILBitManipulationOp(IPOPCNT, result, value));
 571         } else {
 572             append(new HSAILBitManipulationOp(LPOPCNT, result, value));
 573         }
 574     }
 575 
 576     @Override
 577     public void emitBitScanForward(Variable result, Value value) {
 578         throw new InternalError("NYI");
 579     }
 580 
 581     @Override
 582     public void emitBitScanReverse(Variable result, Value value) {
 583         throw new InternalError("NYI");
 584     }




  30 
  31 import com.oracle.graal.api.code.*;
  32 import com.oracle.graal.api.meta.*;
  33 import com.oracle.graal.asm.*;
  34 import com.oracle.graal.compiler.gen.*;
  35 import com.oracle.graal.compiler.target.*;
  36 import com.oracle.graal.debug.*;
  37 import com.oracle.graal.graph.*;
  38 import com.oracle.graal.lir.*;
  39 import com.oracle.graal.lir.StandardOp.JumpOp;
  40 import com.oracle.graal.lir.hsail.*;
  41 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack;
  42 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Reg;
  43 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Stack;
  44 import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp;
  45 import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp;
  46 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
  47 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp;
  48 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp;
  49 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
  50 import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoOp0;
  51 import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoOp1;
  52 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
  53 import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
  54 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp;
  55 import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp;
  56 import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
  57 import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer;
  58 import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer;
  59 import com.oracle.graal.nodes.*;
  60 import com.oracle.graal.nodes.calc.*;
  61 import com.oracle.graal.nodes.java.*;
  62 import com.oracle.graal.hotspot.*;
  63 import com.oracle.graal.hotspot.meta.*;
  64 
  65 /**
  66  * This class implements the HSAIL specific portion of the LIR generator.
  67  */
  68 public class HSAILLIRGenerator extends LIRGenerator {
  69 
  70     private HotSpotRuntime runtime() {
  71         return (HotSpotRuntime) runtime;
  72     }
  73 
  74     public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
  75 
  76         @Override
  77         public LIRInstruction createMove(AllocatableValue dst, Value src) {
  78             if (src instanceof HSAILAddressValue) {
  79                 return new LeaOp(dst, (HSAILAddressValue) src);
  80             } else if (isRegister(src) || isStackSlot(dst)) {
  81                 return new MoveFromRegOp(dst, src);
  82             } else {
  83                 return new MoveToRegOp(dst, src);
  84             }
  85         }
  86     }
  87 
  88     public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
  89         super(graph, runtime, target, frameMap, cc, lir);
  90         lir.spillMoveFactory = new HSAILSpillMoveFactory();
  91     }
  92 
  93     @Override


 116                 return true;
 117         }
 118     }
 119 
 120     @Override
 121     public Variable emitMove(Value input) {
 122         Variable result = newVariable(input.getKind());
 123         emitMove(result, input);
 124         return result;
 125     }
 126 
 127     @Override
 128     public void emitMove(AllocatableValue dst, Value src) {
 129         if (isRegister(src) || isStackSlot(dst)) {
 130             append(new MoveFromRegOp(dst, src));
 131         } else {
 132             append(new MoveToRegOp(dst, src));
 133         }
 134     }
 135 
 136     protected HSAILAddressValue asAddressValue(Value address) {
 137         if (address instanceof HSAILAddressValue) {
 138             return (HSAILAddressValue) address;
 139         } else {
 140             return emitAddress(address, 0, Value.ILLEGAL, 0);
 141         }
 142     }
 143 
 144     public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) {
 145         AllocatableValue baseRegister;
 146         long finalDisp = displacement;
 147 
 148         if (isConstant(base)) {
 149             if (asConstant(base).isNull()) {
 150                 baseRegister = Value.ILLEGAL;
 151             } else if (asConstant(base).getKind() != Kind.Object) {
 152                 finalDisp += asConstant(base).asLong();
 153                 baseRegister = Value.ILLEGAL;
 154             } else {
 155                 baseRegister = load(base);
 156             }
 157         } else if (base == Value.ILLEGAL) {
 158             baseRegister = Value.ILLEGAL;
 159         } else {
 160             baseRegister = asAllocatable(base);
 161         }
 162         if (index != Value.ILLEGAL) {
 163             if (isConstant(index)) {


 172                     indexRegister = convertedIndex;
 173                 }
 174                 if (baseRegister == Value.ILLEGAL) {
 175                     baseRegister = asAllocatable(indexRegister);
 176                 } else {
 177                     baseRegister = emitAdd(baseRegister, indexRegister);
 178                 }
 179             }
 180         }
 181         return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp);
 182     }
 183 
 184     private HSAILAddressValue asAddress(Value address) {
 185         if (address instanceof HSAILAddressValue) {
 186             return (HSAILAddressValue) address;
 187         } else {
 188             return emitAddress(address, 0, Value.ILLEGAL, 0);
 189         }
 190     }
 191 
 192     private static boolean isCompressCandidate(DeoptimizingNode access) {
 193         return access != null && ((HeapAccess) access).compress();
 194     }
 195 
 196     @Override
 197     public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) {
 198         HSAILAddressValue loadAddress = asAddressValue(address);
 199         Variable result = newVariable(kind);
 200         LIRFrameState state = access != null ? state(access) : null;
 201         assert access == null || access instanceof HeapAccess;
 202         if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
 203             Variable scratch = newVariable(Kind.Long);
 204             append(new LoadCompressedPointer(kind, result, scratch, loadAddress, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
 205         } else {
 206             append(new LoadOp(kind, result, loadAddress, state));
 207         }
 208         return result;
 209     }
 210 
 211     @Override
 212     public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) {
 213         HSAILAddressValue storeAddress = asAddressValue(address);
 214         LIRFrameState state = access != null ? state(access) : null;
 215         Variable input = load(inputVal);
 216         if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
 217             Variable scratch = newVariable(Kind.Long);
 218             append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
 219         } else {
 220             append(new StoreOp(kind, storeAddress, input, state));
 221         }
 222     }
 223 
 224     @Override
 225     public Variable emitAddress(StackSlot address) {
 226         throw new InternalError("NYI");
 227     }
 228 
 229     @Override
 230     public void emitJump(LabelRef label) {
 231         append(new JumpOp(label));
 232     }
 233 
 234     private static HSAILCompare mapKindToCompareOp(Kind kind) {
 235         switch (kind) {
 236             case Int:
 237                 return ICMP;
 238             case Long:
 239                 return LCMP;
 240             case Float:
 241                 return FCMP;


 478         return result;
 479     }
 480 
 481     @Override
 482     public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) {
 483         throw new InternalError("NYI");
 484     }
 485 
 486     @Override
 487     public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) {
 488         throw new InternalError("NYI");
 489     }
 490 
 491     @Override
 492     public Variable emitAnd(Value a, Value b) {
 493         Variable result = newVariable(a.getKind());
 494         switch (a.getKind()) {
 495             case Int:
 496                 append(new Op2Stack(IAND, result, a, loadNonConst(b)));
 497                 break;
 498             case Long:
 499                 append(new Op2Stack(LAND, result, a, loadNonConst(b)));
 500                 break;
 501             default:
 502                 throw GraalInternalError.shouldNotReachHere();
 503         }
 504         return result;
 505     }
 506 
 507     @Override
 508     public Variable emitOr(Value a, Value b) {
 509         throw new InternalError("NYI");
 510     }
 511 
 512     @Override
 513     public Variable emitXor(Value a, Value b) {
 514         throw new InternalError("NYI");
 515     }
 516 
 517     @Override
 518     public Variable emitShl(Value a, Value b) {
 519         Variable result = newVariable(a.getKind());
 520         switch (a.getKind()) {
 521             case Int:
 522                 append(new ShiftOp(ISHL, result, a, b));
 523                 break;
 524             case Long:
 525                 append(new ShiftOp(LSHL, result, a, b));
 526                 break;
 527             default:
 528                 GraalInternalError.shouldNotReachHere();
 529         }
 530         return result;
 531     }
 532 
 533     @Override
 534     public Variable emitShr(Value a, Value b) {
 535         throw new InternalError("NYI");
 536     }
 537 
 538     @Override
 539     public Variable emitUShr(Value a, Value b) {
 540         Variable result = newVariable(a.getKind());
 541         switch (a.getKind()) {
 542             case Int:
 543                 append(new ShiftOp(IUSHR, result, a, b));
 544                 break;
 545             case Long:
 546                 append(new ShiftOp(LUSHR, result, a, b));
 547                 break;
 548             default:
 549                 GraalInternalError.shouldNotReachHere();
 550         }
 551         return result;
 552     }
 553 
 554     @Override
 555     public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
 556         Variable input = load(inputVal);
 557         Variable result = newVariable(opcode.to);
 558         switch (opcode) {
 559             case I2F:
 560                 append(new Op1Stack(I2F, result, input));
 561                 break;
 562             case I2L:
 563                 append(new Op1Stack(I2L, result, input));
 564                 break;
 565             case I2D:
 566                 append(new Op1Stack(I2D, result, input));
 567                 break;


 588         append(new ReturnOp(Value.ILLEGAL));
 589     }
 590 
 591     @Override
 592     public void emitMembar(int barriers) {
 593         throw new InternalError("NYI");
 594     }
 595 
 596     @Override
 597     protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
 598         throw new InternalError("NYI");
 599     }
 600 
 601     @Override
 602     protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
 603         throw new InternalError("NYI");
 604     }
 605 
 606     @Override
 607     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
 608         String callName = linkage.getDescriptor().getName();
 609         if (callName.equals("createOutOfBoundsException") || callName.equals("createNullPointerException")) {
 610             // hack Alert !!
 611             switch (arguments.length) {
 612                 case 0:
 613                     append(new ForeignCallNoOp0(callName, result));
 614                     break;
 615                 case 1:
 616                     append(new ForeignCallNoOp1(callName, result, arguments[0]));
 617                     break;
 618                 default:
 619                     throw new InternalError("NYI emitForeignCall");
 620             }
 621 
 622         } else {
 623             throw new InternalError("NYI emitForeignCall");
 624         }
 625     }
 626 
 627     @Override
 628     public void emitBitCount(Variable result, Value value) {
 629         if (value.getKind().getStackKind() == Kind.Int) {
 630             append(new HSAILBitManipulationOp(IPOPCNT, result, value));
 631         } else {
 632             append(new HSAILBitManipulationOp(LPOPCNT, result, value));
 633         }
 634     }
 635 
 636     @Override
 637     public void emitBitScanForward(Variable result, Value value) {
 638         throw new InternalError("NYI");
 639     }
 640 
 641     @Override
 642     public void emitBitScanReverse(Variable result, Value value) {
 643         throw new InternalError("NYI");
 644     }