Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ Compile::Compile(ciEnv* ci_env, ciMethod* target, int osr_bci,
_allow_macro_nodes(true),
_inlining_progress(false),
_inlining_incrementally(false),
_strength_reduction(false),
_do_cleanup(false),
_has_reserved_stack_access(target->has_reserved_stack_access()),
_has_circular_inline_type(false),
Expand Down Expand Up @@ -2775,6 +2776,7 @@ void Compile::process_late_inline_calls_no_inline(PhaseIterGVN& igvn) {
// Tracking and verification of modified nodes is disabled by setting "_modified_nodes == nullptr"
// as if "inlining_incrementally() == true" were set.
assert(inlining_incrementally() == false, "not allowed");
set_strength_reduction(true);
#ifdef ASSERT
Unique_Node_List* modified_nodes = _modified_nodes;
_modified_nodes = nullptr;
Expand All @@ -2792,6 +2794,7 @@ void Compile::process_late_inline_calls_no_inline(PhaseIterGVN& igvn) {
inline_incrementally_cleanup(igvn);
}
DEBUG_ONLY( _modified_nodes = modified_nodes; )
set_strength_reduction(false);
}

bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/opto/compile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ class Compile : public Phase {
bool _major_progress;
bool _inlining_progress; // progress doing incremental inlining?
bool _inlining_incrementally;// Are we doing incremental inlining (post parse)
bool _strength_reduction; // Are we doing strength reduction to direct call
bool _do_cleanup; // Cleanup is needed before proceeding with incremental inlining
bool _has_loops; // True if the method _may_ have some loops
bool _has_split_ifs; // True if the method _may_ have some split-if
Expand Down Expand Up @@ -607,6 +608,8 @@ class Compile : public Phase {
int inlining_progress() const { return _inlining_progress; }
void set_inlining_incrementally(bool z) { _inlining_incrementally = z; }
int inlining_incrementally() const { return _inlining_incrementally; }
void set_strength_reduction(bool z) { _strength_reduction = z; }
bool strength_reduction() const { return _strength_reduction; }
void set_do_cleanup(bool z) { _do_cleanup = z; }
int do_cleanup() const { return _do_cleanup; }
bool major_progress() const { return _major_progress; }
Expand Down
94 changes: 56 additions & 38 deletions src/hotspot/share/opto/graphKit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "asm/register.hpp"
#include "ci/ciFlatArrayKlass.hpp"
#include "ci/ciInlineKlass.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciObjArray.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/javaClasses.hpp"
Expand Down Expand Up @@ -2039,45 +2040,52 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
IdealKit ideal(this);
IdealVariable res(ideal);
ideal.declarations_done();
ideal.if_then(ret, BoolTest::eq, ideal.makecon(TypePtr::NULL_PTR)); {
// Return value is null
ideal.set(res, makecon(TypePtr::NULL_PTR));
} ideal.else_(); {
// Return value is non-null
sync_kit(ideal);

// Change return type of call to scalarized return
const TypeFunc* tf = call->_tf;
const TypeTuple* domain = OptoRuntime::store_inline_type_fields_Type()->domain_cc();
const TypeFunc* new_tf = TypeFunc::make(tf->domain_sig(), tf->domain_cc(), tf->range_sig(), domain);
call->_tf = new_tf;
_gvn.set_type(call, call->Value(&_gvn));
_gvn.set_type(ret, ret->Value(&_gvn));

Node* store_to_buf_call = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
OptoRuntime::store_inline_type_fields_Type(),
StubRoutines::store_inline_type_fields_to_buf(),
nullptr, TypePtr::BOTTOM, ret);

// We don't know how many values are returned. This assumes the
// worst case, that all available registers are used.
for (uint i = TypeFunc::Parms+1; i < domain->cnt(); i++) {
if (domain->field_at(i) == Type::HALF) {
store_to_buf_call->init_req(i, top());
continue;
// Change return type of call to scalarized return
const TypeFunc* tf = call->_tf;
const TypeTuple* domain = OptoRuntime::store_inline_type_fields_Type()->domain_cc();
const TypeFunc* new_tf = TypeFunc::make(tf->domain_sig(), tf->domain_cc(), tf->range_sig(), domain);
call->_tf = new_tf;
_gvn.set_type(call, call->Value(&_gvn));
_gvn.set_type(ret, ret->Value(&_gvn));
// Don't add store to buffer call if we are strength reducing
if (!C->strength_reduction()) {
ideal.if_then(ret, BoolTest::eq, ideal.makecon(TypePtr::NULL_PTR)); {
// Return value is null
ideal.set(res, makecon(TypePtr::NULL_PTR));
} ideal.else_(); {
// Return value is non-null
sync_kit(ideal);

Node* store_to_buf_call = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
OptoRuntime::store_inline_type_fields_Type(),
StubRoutines::store_inline_type_fields_to_buf(),
nullptr, TypePtr::BOTTOM, ret);

// We don't know how many values are returned. This assumes the
// worst case, that all available registers are used.
for (uint i = TypeFunc::Parms+1; i < domain->cnt(); i++) {
if (domain->field_at(i) == Type::HALF) {
store_to_buf_call->init_req(i, top());
continue;
}
Node* proj =_gvn.transform(new ProjNode(call, i));
store_to_buf_call->init_req(i, proj);
}
Node* proj =_gvn.transform(new ProjNode(call, i));
store_to_buf_call->init_req(i, proj);
}
make_slow_call_ex(store_to_buf_call, env()->Throwable_klass(), false);
make_slow_call_ex(store_to_buf_call, env()->Throwable_klass(), false);

Node* buf = _gvn.transform(new ProjNode(store_to_buf_call, TypeFunc::Parms));
const Type* buf_type = TypeOopPtr::make_from_klass(t->as_klass())->join_speculative(TypePtr::NOTNULL);
buf = _gvn.transform(new CheckCastPPNode(control(), buf, buf_type));
Node* buf = _gvn.transform(new ProjNode(store_to_buf_call, TypeFunc::Parms));
const Type* buf_type = TypeOopPtr::make_from_klass(t->as_klass())->join_speculative(TypePtr::NOTNULL);
buf = _gvn.transform(new CheckCastPPNode(control(), buf, buf_type));

ideal.set(res, buf);
ideal.sync_kit(this);
} ideal.end_if();
ideal.set(res, buf);
ideal.sync_kit(this);
} ideal.end_if();
} else {
for (uint i = TypeFunc::Parms+1; i < domain->cnt(); i++) {
Node* proj =_gvn.transform(new ProjNode(call, i));
}
ideal.set(res, ret);
}
sync_kit(ideal);
ret = _gvn.transform(ideal.value(res));
}
Expand Down Expand Up @@ -2218,9 +2226,19 @@ void GraphKit::replace_call(CallNode* call, Node* result, bool do_replaced_nodes
if (callprojs->resproj[0] != nullptr && result != nullptr) {
// If the inlined code is dead, the result projections for an inline type returned as
// fields have not been replaced. They will go away once the call is replaced by TOP below.
assert(callprojs->nb_resproj == 1 || (call->tf()->returns_inline_type_as_fields() && stopped()),
assert(callprojs->nb_resproj == 1 || (call->tf()->returns_inline_type_as_fields() && stopped()) ||
(C->strength_reduction() && InlineTypeReturnedAsFields && !call->as_CallJava()->method()->return_type()->is_loaded()),
"unexpected number of results");
C->gvn_replace_by(callprojs->resproj[0], result);
// If we are doing strength reduction and the return type is not loaded we
// need to rewire all projections since store_inline_type_fields_to_buf is already present
if (C->strength_reduction() && InlineTypeReturnedAsFields && !call->as_CallJava()->method()->return_type()->is_loaded()) {
const TypeTuple* domain = OptoRuntime::store_inline_type_fields_Type()->domain_cc();
for (uint i = TypeFunc::Parms; i < domain->cnt(); i++) {
C->gvn_replace_by(callprojs->resproj[0], final_state->in(i));
}
} else {
C->gvn_replace_by(callprojs->resproj[0], result);
}
}

if (ejvms == nullptr) {
Expand Down
1 change: 0 additions & 1 deletion test/hotspot/jtreg/ProblemList-enable-preview.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ compiler/c2/irTests/stable/StableRefFinalTest.java
compiler/c2/irTests/stable/StableRefPlainTest.java 8372700 generic-all
compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java 8372605 generic-all
compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java 8372605 generic-all
runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/ArrayIndexOutOfBoundsExceptionTest.java#id1 8369045 macosx-aarch64

# Runtime (all Valhalla):
runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java 8372602 generic-all
Expand Down
4 changes: 0 additions & 4 deletions test/jdk/ProblemList-Xcomp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,3 @@

java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all
java/lang/reflect/callerCache/ReflectionCallerCacheTest.java 8332028 generic-all
valhalla/valuetypes/ObjectMethodsViaCondy.java 8369045 macosx-all
valhalla/valuetypes/ObjectNewInstance.java 8369045 macosx-all
valhalla/valuetypes/ProxyTest.java 8369045 macosx-all
valhalla/valuetypes/WeakReferenceTest.java 8369045 macosx-all
3 changes: 0 additions & 3 deletions test/jdk/ProblemList-enable-preview.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
java/foreign/TestRestricted.java 8372744 generic-all
java/lang/module/ModuleReader/ModuleReaderTest.java 8372744 generic-all
java/lang/module/ModuleReader/patched/PatchedModuleReaderTest.java 8372744 generic-all
java/lang/StackWalker/LocalsAndOperands.java#id0 8369045 macosx-all
java/lang/StackWalker/LocalsAndOperands.java#id1 8369045 macosx-all
java/lang/StringBuilder/CompactStringBuilder.java 8369045 macosx-all
java/foreign/sharedclosejvmti/TestSharedCloseJvmti.java 8372745 generic-all
java/util/Map/MapBinToFromTreeTest.java 8373878 linux-aarch64
java/util/NavigableMap/LockStep.java 8372824 generic-all
Expand Down