< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java

Print this page
rev 56282 : [mq]: graal


 282         return getResult().getStub() != null;
 283     }
 284 
 285     private LIRFrameState currentRuntimeCallInfo;
 286 
 287     @Override
 288     protected void emitForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
 289         currentRuntimeCallInfo = info;
 290         HotSpotForeignCallLinkage hsLinkage = (HotSpotForeignCallLinkage) linkage;
 291         AMD64 arch = (AMD64) target().arch;
 292         if (arch.getFeatures().contains(AMD64.CPUFeature.AVX) && hsLinkage.mayContainFP() && !hsLinkage.isCompiledStub()) {
 293             /*
 294              * If the target may contain FP ops, and it is not compiled by us, we may have an
 295              * AVX-SSE transition.
 296              *
 297              * We exclude the argument registers from the zeroing LIR instruction since it violates
 298              * the LIR semantics of @Temp that values must not be live. Note that the emitted
 299              * machine instruction actually zeros _all_ XMM registers which is fine since we know
 300              * that their upper half is not used.
 301              */
 302             append(new AMD64VZeroUpper(arguments));
 303         }
 304         super.emitForeignCallOp(linkage, result, arguments, temps, info);
 305     }
 306 
 307     /**
 308      * @param savedRegisters the registers saved by this operation which may be subject to pruning
 309      * @param savedRegisterLocations the slots to which the registers are saved
 310      * @param supportsRemove determines if registers can be pruned
 311      */
 312     protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations, boolean supportsRemove) {
 313         AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove);
 314         append(save);
 315         return save;
 316     }
 317 
 318     /**
 319      * Allocate a stack slot for saving a register.
 320      */
 321     protected VirtualStackSlot allocateSaveRegisterLocation(Register register) {
 322         PlatformKind kind = target().arch.getLargestStorableKind(register.getRegisterCategory());
 323         if (kind.getVectorLength() > 1) {
 324             // we don't use vector registers, so there is no need to save them
 325             kind = AMD64Kind.DOUBLE;
 326         }
 327         return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
 328     }
 329 
 330     /**
 331      * Adds a node to the graph that saves all allocatable registers to the stack.
 332      *
 333      * @param supportsRemove determines if registers can be pruned
 334      * @return the register save node
 335      */
 336     private AMD64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) {

 337         AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length];
 338         for (int i = 0; i < savedRegisters.length; i++) {
 339             savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]);
 340         }
 341         return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove);




 342     }
 343 
 344     protected void emitRestoreRegisters(AMD64SaveRegistersOp save) {
 345         append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save));
 346     }
 347 
 348     /**
 349      * Gets the {@link Stub} this generator is generating code for or {@code null} if a stub is not
 350      * being generated.
 351      */
 352     public Stub getStub() {
 353         return getResult().getStub();
 354     }
 355 
 356     @Override
 357     public HotSpotLIRGenerationResult getResult() {
 358         return ((HotSpotLIRGenerationResult) super.getResult());
 359     }
 360 
 361     public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) {
 362         this.debugInfoBuilder = debugInfoBuilder;
 363     }
 364 
 365     @Override
 366     public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) {
 367         HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
 368         boolean destroysRegisters = hotspotLinkage.destroysRegisters();
 369 
 370         AMD64SaveRegistersOp save = null;
 371         Stub stub = getStub();
 372         if (destroysRegisters) {
 373             if (stub != null && stub.preservesRegisters()) {
 374                 Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray();
 375                 save = emitSaveAllRegisters(savedRegisters, true);
 376             }
 377         }
 378 
 379         Variable result;
 380         LIRFrameState debugInfo = null;
 381         if (hotspotLinkage.needsDebugInfo()) {
 382             debugInfo = state;
 383             assert debugInfo != null || stub != null;
 384         }
 385 
 386         if (hotspotLinkage.needsJavaFrameAnchor()) {
 387             Register thread = getProviders().getRegisters().getThreadRegister();
 388             append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
 389             result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
 390             append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), config.threadLastJavaPcOffset(), thread));
 391         } else {
 392             result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
 393         }
 394 
 395         if (destroysRegisters) {
 396             if (stub != null) {
 397                 if (stub.preservesRegisters()) {
 398                     HotSpotLIRGenerationResult generationResult = getResult();
 399                     LIRFrameState key = currentRuntimeCallInfo;
 400                     if (key == null) {
 401                         key = LIRFrameState.NO_STATE;
 402                     }
 403                     assert !generationResult.getCalleeSaveInfo().containsKey(key);
 404                     generationResult.getCalleeSaveInfo().put(key, save);
 405                     emitRestoreRegisters(save);
 406                 }
 407             }
 408         }
 409 
 410         return result;
 411     }
 412 
 413     @Override
 414     public Value emitLoadObjectAddress(Constant constant) {
 415         HotSpotObjectConstant objectConstant = (HotSpotObjectConstant) constant;
 416         LIRKind kind = objectConstant.isCompressed() ? getLIRKindTool().getNarrowOopKind() : getLIRKindTool().getObjectKind();
 417         Variable result = newVariable(kind);
 418         append(new AMD64HotSpotLoadAddressOp(result, constant, HotSpotConstantLoadAction.RESOLVE));
 419         return result;
 420     }
 421 
 422     @Override
 423     public Value emitLoadMetaspaceAddress(Constant constant, HotSpotConstantLoadAction action) {
 424         HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) constant;
 425         LIRKind kind = metaspaceConstant.isCompressed() ? getLIRKindTool().getNarrowPointerKind() : getLIRKindTool().getWordKind();
 426         Variable result = newVariable(kind);
 427         append(new AMD64HotSpotLoadAddressOp(result, constant, action));




 282         return getResult().getStub() != null;
 283     }
 284 
 285     private LIRFrameState currentRuntimeCallInfo;
 286 
 287     @Override
 288     protected void emitForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
 289         currentRuntimeCallInfo = info;
 290         HotSpotForeignCallLinkage hsLinkage = (HotSpotForeignCallLinkage) linkage;
 291         AMD64 arch = (AMD64) target().arch;
 292         if (arch.getFeatures().contains(AMD64.CPUFeature.AVX) && hsLinkage.mayContainFP() && !hsLinkage.isCompiledStub()) {
 293             /*
 294              * If the target may contain FP ops, and it is not compiled by us, we may have an
 295              * AVX-SSE transition.
 296              *
 297              * We exclude the argument registers from the zeroing LIR instruction since it violates
 298              * the LIR semantics of @Temp that values must not be live. Note that the emitted
 299              * machine instruction actually zeros _all_ XMM registers which is fine since we know
 300              * that their upper half is not used.
 301              */
 302             append(new AMD64VZeroUpper(arguments, getRegisterConfig()));
 303         }
 304         super.emitForeignCallOp(linkage, result, arguments, temps, info);
 305     }
 306 
 307     /**
 308      * @param savedRegisters the registers saved by this operation which may be subject to pruning
 309      * @param savedRegisterLocations the slots to which the registers are saved

 310      */
 311     protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) {
 312         AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations);
 313         append(save);
 314         return save;
 315     }
 316 
 317     /**
 318      * Allocate a stack slot for saving a register.
 319      */
 320     protected VirtualStackSlot allocateSaveRegisterLocation(Register register) {
 321         PlatformKind kind = target().arch.getLargestStorableKind(register.getRegisterCategory());
 322         if (kind.getVectorLength() > 1) {
 323             // we don't use vector registers, so there is no need to save them
 324             kind = AMD64Kind.DOUBLE;
 325         }
 326         return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
 327     }
 328 
 329     /**
 330      * Adds a node to the graph that saves all allocatable registers to the stack.
 331      *

 332      * @return the register save node
 333      */
 334     private AMD64SaveRegistersOp emitSaveAllRegisters() {
 335         Register[] savedRegisters = getSaveableRegisters();
 336         AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length];
 337         for (int i = 0; i < savedRegisters.length; i++) {
 338             savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]);
 339         }
 340         return emitSaveRegisters(savedRegisters, savedRegisterLocations);
 341     }
 342 
 343     protected Register[] getSaveableRegisters() {
 344         return getResult().getRegisterAllocationConfig().getAllocatableRegisters().toArray();
 345     }
 346 
 347     protected void emitRestoreRegisters(AMD64SaveRegistersOp save) {
 348         append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save));
 349     }
 350 
 351     /**
 352      * Gets the {@link Stub} this generator is generating code for or {@code null} if a stub is not
 353      * being generated.
 354      */
 355     public Stub getStub() {
 356         return getResult().getStub();
 357     }
 358 
 359     @Override
 360     public HotSpotLIRGenerationResult getResult() {
 361         return ((HotSpotLIRGenerationResult) super.getResult());
 362     }
 363 
 364     public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) {
 365         this.debugInfoBuilder = debugInfoBuilder;
 366     }
 367 
 368     @Override
 369     public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) {
 370         HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
 371         boolean destroysRegisters = hotspotLinkage.destroysRegisters();
 372 
 373         AMD64SaveRegistersOp save = null;
 374         Stub stub = getStub();
 375         if (destroysRegisters && stub != null && stub.shouldSaveRegistersAroundCalls()) {
 376             save = emitSaveAllRegisters();



 377         }
 378 
 379         Variable result;
 380         LIRFrameState debugInfo = null;
 381         if (hotspotLinkage.needsDebugInfo()) {
 382             debugInfo = state;
 383             assert debugInfo != null || stub != null;
 384         }
 385 
 386         if (hotspotLinkage.needsJavaFrameAnchor()) {
 387             Register thread = getProviders().getRegisters().getThreadRegister();
 388             append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
 389             result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
 390             append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), config.threadLastJavaPcOffset(), thread));
 391         } else {
 392             result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
 393         }
 394 
 395         if (save != null) {


 396             HotSpotLIRGenerationResult generationResult = getResult();
 397             LIRFrameState key = currentRuntimeCallInfo;
 398             if (key == null) {
 399                 key = LIRFrameState.NO_STATE;
 400             }
 401             assert !generationResult.getCalleeSaveInfo().containsKey(key);
 402             generationResult.getCalleeSaveInfo().put(key, save);
 403             emitRestoreRegisters(save);


 404         }
 405 
 406         return result;
 407     }
 408 
 409     @Override
 410     public Value emitLoadObjectAddress(Constant constant) {
 411         HotSpotObjectConstant objectConstant = (HotSpotObjectConstant) constant;
 412         LIRKind kind = objectConstant.isCompressed() ? getLIRKindTool().getNarrowOopKind() : getLIRKindTool().getObjectKind();
 413         Variable result = newVariable(kind);
 414         append(new AMD64HotSpotLoadAddressOp(result, constant, HotSpotConstantLoadAction.RESOLVE));
 415         return result;
 416     }
 417 
 418     @Override
 419     public Value emitLoadMetaspaceAddress(Constant constant, HotSpotConstantLoadAction action) {
 420         HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) constant;
 421         LIRKind kind = metaspaceConstant.isCompressed() ? getLIRKindTool().getNarrowPointerKind() : getLIRKindTool().getWordKind();
 422         Variable result = newVariable(kind);
 423         append(new AMD64HotSpotLoadAddressOp(result, constant, action));


< prev index next >